2009-07-01 4 views

답변

3

클래스 본문은 자체가 정의 된 클래스보다 먼저 실행되므로 기본 인수 값은 클래스를 참조 할 수 없습니다. custom을 기본값 (클래스 자격없이)으로 설정하면됩니다.

11

너가 그것의 중간에 있기 때문에 그것은 보이지 않아 .Foo이다.

class Foo(object): 
    custom = 1 
    def __init__(self, mycustom=custom): 
     self._custom = mycustom 

을하지만 나중에 Foo.custom을 변경하면 Foo의보고 이후에 생성 된 custom의 값에 영향을 미치지 않습니다 : 당신이 custom 같은 범위에있어 이후, 당신은 단지 custom보다는 Foo.custom을 말할 수있다 :

class Foo(object): 
    custom = 1 
    def __init__(self, mycustom=custom): 
     self._custom = mycustom 

one = Foo() 
Foo.custom = 2 
two = Foo() 
print (two._custom) # Prints 1 

대신 감시 기본값을 사용함으로써, 당신은 당신이 원하는 것을 얻을 수 있습니다

class Foo(object): 
    custom = 1 
    def __init__(self, mycustom=None): 
     if mycustom is None: 
      self._custom = Foo.custom 
     else: 
      self._custom = mycustom 

one = Foo() 
Foo.custom = 2 
two = Foo() 
print (two._custom) # Prints 2 
+0

None과의 비교를 제외하고 항상 nice는 'is'를 통해 수행되어야합니다. –

+0

"나중에 Foo.custom을 변경해도 이후에 생성 된 Foos에서 볼 수있는 사용자 정의 값에 영향을 미치지는 않지만 그 의미는 있습니다."기본 값이 생성되고 한 번만 바인딩되는 함수의 경우 항상 그렇다는 점을 지적하십시오. 함수가 만들어 지므로 Foo.custom을 기본값으로 참조 할 수 있다면 * Foo.custom이 변경되면 기본값이 변경되지 않을 수도 있습니다. – Miles

+0

Foo.custom을 __init__ 본문에서 참조 할 수 있지만 이니셜 라이저 목록에서 참조 할 수없는 이유는 무엇입니까? 두 경우 모두에서 "우리는 건물을 짓고있는 중입니다." –

2

나는 다음과 같은 오류가 발생합니다 :

Traceback (most recent call last): 
    Line 1, in <module> 
    class Foo(object): 
    Line 3, in Foo 
    def __init__(self, custom=Foo.custom): 
NameError: name 'Foo' is not defined 

이름 Foo__init__ 함수가 정의로 정의되는 과정에 있고, 그 시간에 완전히 사용할 수 없습니다 때문입니다.

class Foo(object): 
    custom = 1 
    def __init__(self, acustom=custom): 
     self._custom = acustom 
x = Foo() 
print x._custom 
+0

하지만 이니셜 라이저 목록뿐만 아니라 _body_ of __init__에서 Foo.custom을 참조 할 수 있다는 것을 알고 있습니다. 이렇게하면 일관성이 없습니다. –

+0

"Foo.custom과 구별하기 위해 커스텀 매개 변수의 이름을 변경했습니다."이것은 아마도 좋은 생각 일 뿐이지 만 엄격하게 필요하지는 않습니다. 그리고 어떤 상황에서는 파이썬에서도 같은 것을 사용하는 관용구입니다 루프 내부에 중첩 된 함수가 있음, 예 : lambda x = x : ...) – Miles

6

우리가 대신 할 것은 다음과 같은

입니다 :

이 솔루션은 함수 정의에 이름 Foo을 사용하지 않도록하는 것입니다 (나는 또한 Foo.custom과 구별하기 위해 acustomcustom 있었던 파라미터의 이름을 변경)

class Foo(object): 
    custom = 1 
    def __init__(self, arg=None) 
     self._custom = self.custom if arg is None else arg 

이것은 Foo 이름이 아직 정의되어 있는지 여부에 대한 혼란스러운 문제를 우회합니다.

+0

왜 혼란 스럽습니까? 인스턴스가 생성되기 전에 클래스가 초기화되어야합니다. __init__은 인스턴스가 생성 될 때 실행되기 때문에 클래스 변수가 보일 것입니다. –

+0

@rdm : 내 대답에 대한 Miles의 의견을 확인하십시오. 기본 매개 변수는 함수를 만들 때 (즉,이 경우 클래스를 만드는 동안) 결정되며, 호출 할 때 결정되지 않습니다. – RichieHindle

관련 문제