2010-04-28 4 views
4
import inspect 
class Test: 
    def test(self, p, d={}): 
    d.update(p) 
    return d 
print inspect.getargspec(getattr(Test, 'test'))[3] 
print Test().test({'1':True}) 
print inspect.getargspec(getattr(Test, 'test'))[3] 

나는 Test Test에 대한 argspec이 dict.update 때문에 변경되지 않기를 기대합니다. 왜?dict.update가 함수의 argspec에 영향을 줍니까?

답변

5

dicts는 변경 가능한 개체이기 때문에. d.update(p)을 호출하면 실제로 dict의 기본 인스턴스가 변경됩니다. 이것은 일반적인 잡기입니다. 특히 은 가변 인수를 인수 목록에서 기본값으로 사용해야합니다.

이 작업을 수행하는 더 좋은 방법은 다음과 같습니다

class Test: 
    def test(self, p, d = None): 
     if d is None: 
      d = {} 
     d.update(p) 
     return d 
+1

'D = d 나 {}'는 누군가가 자신의 * dict 객체를 넘겨 주면 누군가가 당신이 변형시킨 것들을 가지고 * 누군가 자신의 * dict 객체 (또는 그것과 비슷한 종류의 다른 객체)를 넘겨 주면 이상하다. 즉 비어있는 경우 새로운 dict 객체를 대신 사용합니다. 이런 식으로 코드를 작성했다면'd가 None이면 : d = {}'를 사용하거나 아마 내가 시작하는 인수를 돌연변이시키지 않을 것입니다. –

+0

여기에 요점이 있습니다.이를 수용 할 수있는 솔루션을 편집 중입니다. 어쨌든, 나는 또한 거기에서받은 논쟁을 돌연변이 시켜서는 안된다는 것에 동의한다. –

2

파이썬에서 기본 인수가 어떤 객체 것은 당신이 변경 가능한 객체를 설정 한 경우에도, 함수가 정의 될 때 설정됩니다. 이 질문은 그것이 무엇을 의미하는지, 그리고 왜 파이썬이 SO 질문이냐고 설명해야합니다. least astonishment in python: the mutable default argument.

기본적으로 동일한 기본 개체는 매번 새로운 복사본이 만들어지기보다는 함수가 호출 될 때마다 사용됩니다. 예를 들어 :

>>> def f(xs=[]): 
... xs.append(5) 
... print xs 
... 
>>> f() 
[5] 
>>> f() 
[5, 5] 

이 주변에 가장 쉬운 방법은 예를 들어, 실제 기본 인수 None 확인한 다음 단순히 None 확인하고 기능에 기본을 제공하는 것입니다 :

>>> def f(xs=None): 
... if xs is None: 
...  xs = [] 
... xs.append(5) 
... print xs 
... 
>>> f() 
[5] 
>>> f() 
[5] 
+1

"파이썬의 기본 인수는 변경할 수 있습니다." 전적으로 사실이 아니다. 기본 인수는 변경 가능 (목록과 같은 변경 가능한 객체 일 때) 및 변경 불가능 (int와 같이 불변 인 경우) 일 수 있습니다. 다소 중요한 부분은 기본 인수로 하나의 객체 만 설정된다는 것입니다. –

+0

@Mike : 좋은 지적, 나는 그 진술의 표현을 개선하기 위해 나의 대답을 편집했다. –

관련 문제