파이썬에서 어떻게 정수를 참조로 전달할 수 있습니까?
함수에 전달하는 변수의 값을 수정하고 싶습니다. 나는 파이썬의 모든 것이 가치로 전달된다는 것을 읽었지만 쉬운 트릭이 있어야합니다. 예를 들어 Java Integer
에서는 Long
, 등 의 참조 유형을 전달할 수 있습니다 .
- 어떻게 정수를 함수에 참조로 전달할 수 있습니까?
- 모범 사례는 무엇입니까?
파이썬에서 어떻게 정수를 참조로 전달할 수 있습니까?
함수에 전달하는 변수의 값을 수정하고 싶습니다. 나는 파이썬의 모든 것이 가치로 전달된다는 것을 읽었지만 쉬운 트릭이 있어야합니다. 예를 들어 Java Integer
에서는 Long
, 등 의 참조 유형을 전달할 수 있습니다 .
답변:
파이썬에서는 그렇게 작동하지 않습니다. 파이썬은 객체에 대한 참조를 전달합니다. 함수 내부에는 객체가 있습니다. 가능하면 해당 객체를 자유롭게 변경할 수 있습니다. 그러나 정수는 변경할 수 없습니다 . 한 가지 해결 방법은 변경 될 수있는 컨테이너에 정수를 전달하는 것입니다.
def change(x):
x[0] = 3
x = [1]
change(x)
print x
이것은 기껏해야 추악하고 어색하지만 파이썬에서 더 잘할 수는 없습니다. 그 이유는 Python에서 할당 ( =
)은 오른쪽의 결과 인 모든 객체를 가져 와서 왼쪽에있는 모든 객체 * (또는 적절한 함수에 전달)에 바인딩하기 때문입니다.
이를 이해하면 함수 내에서 불변 객체의 값을 변경할 수있는 방법이없는 이유를 알 수 있습니다. 불변이기 때문에 속성을 변경할 수 없으며 "변수"에 새 항목을 할당 할 수 없습니다. 값은 실제로 새 객체 (이전 객체와 구별됨)를 만들고 이전 객체가 로컬 네임 스페이스에있는 이름을 지정하기 때문입니다.
일반적으로 해결 방법은 원하는 개체를 반환 하는 것입니다.
def multiply_by_2(x):
return 2*x
x = 1
x = multiply_by_2(x)
* 위의 첫 번째 예에서는 3
실제로 x.__setitem__
.
C
. (예를 들어, 역 참조 할 필요가 없습니다). 내 멘탈 모델에서는 사물을 "이름"과 "대상"으로 생각하는 것이 더 쉽습니다. 할당은 왼쪽의 "이름"을 오른쪽의 "개체"에 바인딩합니다. 함수를 호출 할 때 "Object"를 전달합니다 (함수 내에서 새 로컬 이름에 효과적으로 바인딩).
.
연산자는 단순히 왼쪽을 역 참조합니다. 연산자는 언어마다 다를 수 있습니다.
참조로 전달해야하는 대부분의 경우는 호출자에게 둘 이상의 값을 반환해야하는 경우입니다. "모범 사례"는 여러 반환 값을 사용하는 것입니다. 이는 Java와 같은 언어보다 Python에서 훨씬 더 쉽습니다.
다음은 간단한 예입니다.
def RectToPolar(x, y):
r = (x ** 2 + y ** 2) ** 0.5
theta = math.atan2(y, x)
return r, theta # return 2 things at once
r, theta = RectToPolar(3, 4) # assign 2 things at once
실제로 가장 좋은 방법은 한 걸음 물러서서이 작업이 정말로 필요한지 묻는 것입니다. 함수에 전달하는 변수의 값을 수정하려는 이유 는 무엇 입니까?
빠른 해킹을 위해해야 할 경우 가장 빠른 방법은 list
정수 를 전달하고 [0]
mgilson의 답변에서 알 수 있듯이 정수를 사용할 때마다 사용하는 것입니다.
좀 더 중요한 일을해야한다면 속성 class
이있는 a 를 작성하여 int
설정하면됩니다. 물론 이것은 당신이 수업과 속성에 대한 좋은 이름을 생각해 내도록 강요합니다. 만약 당신이 아무것도 생각할 수 없다면, 돌아가서 문장을 몇 번 다시 읽은 다음 list
.
보다 일반적으로 일부 Java 관용구를 Python으로 직접 이식하려는 경우 잘못하고있는 것입니다. ( static
/ 와 같이) 직접 대응하는 것이 있더라도 @staticmethod
Java에서 사용하기 때문에 대부분의 Python 프로그램에서 사용하고 싶지 않습니다.
NumPy와 단일 소자 어레이는 가변하고 수치 파이썬 변수 것처럼 아직 대부분의 목적을 위해, 그것은 평가 될 수있다. 따라서 단일 요소 목록보다 참조 번호 별 컨테이너가 더 편리합니다.
import numpy as np
def triple_var_by_ref(x):
x[0]=x[0]*3
a=np.array([2])
triple_var_by_ref(a)
print(a+1)
산출:
3
비단뱀적인 방법은 아닐 수도 있지만 이렇게 할 수 있습니다.
import ctypes
def incr(a):
a += 1
x = ctypes.c_int(1) # create c-var
incr(ctypes.ctypes.byref(x)) # passing by ref
list-of-length-1 트릭보다 약간 더 많은 자체 문서화는 오래된 빈 유형 트릭입니다.
def inc_i(v):
v.i += 1
x = type('', (), {})()
x.i = 7
inc_i(x)
print(x.i)
Python에서는 모든 것이 값으로 전달되지만 일부 상태를 수정하려면 메서드에 전달되는 목록 또는 객체 내에서 정수 값을 변경할 수 있습니다.
everything is passed by value
사실이 아니기 때문이라고 생각 합니다. 문서 인용 :arguments are passed using call by value (where the value is always an object reference, not the value of the object)