파이썬으로 오랫동안 땜질을하는 사람은 다음과 같은 문제로 물렸거나 조각났습니다.
def foo(a=[]):
a.append(5)
return a
파이썬 초보자는이 함수가 항상 하나의 요소로만 목록을 반환 할 것으로 기대합니다 [5]
. 결과는 대신 매우 다르며 매우 초보자입니다.
>>> foo()
[5]
>>> foo()
[5, 5]
>>> foo()
[5, 5, 5]
>>> foo()
[5, 5, 5, 5]
>>> foo()
내 관리자는 한 번이 기능을 처음 접했으며 언어의 "극적인 디자인 결함"이라고 불렀습니다. 나는 그 행동이 근본적인 설명을 가지고 있다고 대답했으며, 당신이 내부를 이해하지 못한다면 실제로 매우 당혹스럽고 예상치 못한 것입니다. 그러나 나는 다음과 같은 질문에 스스로 대답 할 수 없었습니다 : 함수 실행이 아닌 함수 정의에서 기본 인수를 바인딩하는 이유는 무엇입니까? 숙련 된 행동이 실제로 사용되는지 의심합니다 (누가 버그없이 C에서 정적 변수를 실제로 사용 했습니까?)
편집 :
Baczek이 흥미로운 예를 만들었습니다. 귀하의 의견과 Utaal의 의견과 함께 더 자세히 설명했습니다.
>>> def a():
... print("a executed")
... return []
...
>>>
>>> def b(x=a()):
... x.append(5)
... print(x)
...
a executed
>>> b()
[5]
>>> b()
[5, 5]
나에게, 디자인 결정은 매개 변수의 범위를 어디에 넣을 것인지에 관한 것 같습니다 : 함수 내부 또는 "함께"?
함수 내에서 바인딩을 수행하면 x
함수가 호출 될 때 지정된 기본값에 효과적으로 바인딩되어 깊은 결함이 def
있는 것을 의미합니다. 함수 객체)는 정의시 발생하고 함수 호출시 부분 (기본 매개 변수 할당)이 발생합니다.
실제 동작은 더 일관성이 있습니다. 해당 행이 실행될 때 해당 행의 모든 것이 평가되므로 함수 정의에서 의미합니다.
[5]
." 나는 파이썬 초보자 해요, 분명히 때문에,이를 기대하지 않을 것이다 foo([1])
반환 [1, 5]
하지 [5]
. 당신이 말하고자하는 것은 초보자는 매개 변수없이 호출 된 함수 가 항상 리턴 할 것이라고 예상한다는 것 [5]
입니다.