2012-07-20 3 views
13

파이썬에서 함수 호출에 대한 질문이 있습니다. superLongFunc (expr)라는 함수를 작성하고 싶다고합시다. 이 함수는 매우 길고 디버깅하기가 정말 어렵습니다. smallFunc1 (expr), smallFunc2 (expr) 등과 같이 좀 더 가독성을 위해 작은 도우미 함수로 나누고 싶습니다.Python - 전달 값은 어떻게 작동합니까?

제 질문은 코드의 성능에 영향을 줍니까? 파이썬에서 호출 함수가 정확히 어떻게 작동합니까? 파이썬은 변수를 참조로 함수에 전달합니까? 또는 변수를 함수에 제공하기 전에 변수의 복사본을 만드나요?

나는 꽤 멍청한 질문이지만 잠시 동안 나를 괴롭혔다. 미리 감사드립니다!

+1

이것을 알아내는 경험적인 방법이 있습니다. 'timeit'과'dis' 모듈이 떠오른다. 때로는 스스로 테스트 할 수있는 것이 유용합니다. –

답변

16

파이썬은 call-by-object라고도하는 시스템을 사용합니다. 함수에 인수를 전달할 때 아무 것도 복사되지 않습니다. 함수 인수의 이름은 함수 본문 내에서 함수 호출에서 제공된 것과 동일한 객체에 로컬로 바인드됩니다.

이것은 개체를 복사하지 않기 때문에 대부분의 사람들이 "값으로 호출"한다고 생각하는 것과 다릅니다. 참조가 개체 --- 새 이름이인데도 동일한 개체가 바인딩되어 있기 때문에 "참조로 호출"과 다릅니다. 즉, 전달 된 오브젝트를 변경할 수는 있지만 함수 내에서 이름을 리 바인드해도 함수 외부에서는 아무 효과가 없습니다. 차이의 간단한 예 : 이것에 대해 생각

>>> def func(x): 
...  x[0] = 2 # Mutating the object affects the object outside the function 
>>> myList = [1] 
>>> func(myList) 
>>> myList # myList has changed 
[2] 
>>> def func(x): 
...  x = 2 # rebinding name has no effect outside the function 
>>> myList = [1] 
>>> func(myList) 
>>> myList # myList is unaffected 
[1] 

내 간단한 방법은 형태 name = value의 문 --- 파이썬에서 다른 모든 것들로부터 완전히 다른 --- 즉, 맨손으로 이름이 할당입니다 . 값을 사용하지 않고 이름을 조작하는 방법은 name = value입니다. (globals() 등으로 주위를 조종하는 등의 단점이 있습니다 만, 이것들은 위험한 지역입니다.) 특히 name = valueobj.prop = value, obj[0] = value, obj += value 및 할당과 비슷하지만 실제로는 객체에서 작동하는 다른 것들과 다릅니다 이름이 아니라.

즉, 파이썬에서의 함수 호출은 그 자체만으로 (실행 프레임을 설정하는 등) 일정량의 오버 헤드가 있습니다. 함수가 여러 번 호출되면이 오버 헤드로 인해 성능에 큰 영향을 줄 수 있습니다. 따라서 하나의 함수를 여러 함수로 분할하는 것은 각 추가 함수 호출이 약간의 오버 헤드를 추가하기 때문에 여전히 성능에 영향을 줄 수 있습니다.

+3

설명하는 것은 값에 의한 호출이며 값은 객체에 대한 참조입니다. – Marcin

+0

예, 객체 별 호출을 설명하는 또 다른 방법입니다. – BrenBarn

+0

또한 적어도 C++에서 구현 된 것과 같이 참조로 호출하는 것과 거의 같습니다. 많은 내장 유형이 파이썬에서 불변입니다. –

관련 문제