문제

파이썬에서 Super () 함수를 배우려고합니다.

나는이 예제 (2.6)에 올 때까지 내가 그것을 이해하고 있다고 생각했다.

http://www.cafepy.com/article/python_attributes_and_methods/python_attributes_and_methods.html#sper-withclassod-example

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "test.py", line 9, in do_something
    do_something = classmethod(do_something)
TypeError: unbound method do_something() must be called with B instance as first argument (got nothing instead)
>>>

예제 직전 에이 줄을 읽었을 때 예상 한 것은 아닙니다.

클래스 메소드를 사용하는 경우 Super와 함께 전화 할 인스턴스가 없습니다. 다행히도 우리에게는 슈퍼가 두 번째 인수로 유형을 가지고조차도 작동합니다. --- 유형은 아래 그림과 같이 슈퍼로 직접 전달할 수 있습니다.

Python이 나에게 말하는 것은 Do_Something ()이 B 인스턴스와 함께 호출되어야한다고 말함으로써 불가능하다는 것입니다.

도움이 되었습니까?

해결책

때로는 세부 사항보다는 아이디어의 맛에 대해 텍스트를 더 읽어야합니다. 이것은 그러한 경우 중 하나입니다.

에서 링크 된 페이지, 예제 2.5, 2.6 및 2.7은 모두 하나의 방법을 사용해야합니다. do_your_stuff. (그건, do_something 변경해야합니다 do_your_stuff.)

또한, AS Ned Deily가 지적했다, A.do_your_stuff 클래스 방법이어야합니다.

class A(object):
    @classmethod
    def do_your_stuff(cls):
        print 'This is A'

class B(A):
    @classmethod
    def do_your_stuff(cls):
        super(B, cls).do_your_stuff()

B.do_your_stuff()

super(B, cls).do_your_stuff반환 a 경계 방법 (참조 각주 2). 부터 cls 두 번째 논쟁으로 통과되었습니다 super(), 그것은이다 cls 반환 된 방법에 결합됩니다. 다시 말해, cls 이 방법에 대한 첫 번째 인수로 전달됩니다 do_your_stuff() 클래스 A의

반복하려면 : super(B, cls).do_your_stuff() 원인 A'에스 do_your_stuff 호출되는 방법 cls 첫 번째 논쟁으로 통과되었습니다. 그것이 작동하기 위해 A'에스do_your_stuff 클래스 방법이어야합니다. 링크 된 페이지는 그것을 언급하지 않지만 그것은 확실히 그렇습니다.

추신. do_something = classmethod(do_something) 급류를 만드는 오래된 방법입니다. 새로운 (ER) 방법은 @ClassMethod 데코레이터를 사용하는 것입니다.


주목하십시오 super(B, cls) 대체 할 수 없습니다 super(cls, cls). 그렇게하면 무한 루프가 발생할 수 있습니다. 예를 들어,

class A(object):
    @classmethod
    def do_your_stuff(cls):
        print('This is A')

class B(A):
    @classmethod
    def do_your_stuff(cls):
        print('This is B')
        # super(B, cls).do_your_stuff()  # CORRECT
        super(cls, cls).do_your_stuff()  # WRONG

class C(B):
    @classmethod
    def do_your_stuff(cls):
        print('This is C')
        # super(C, cls).do_your_stuff()  # CORRECT
        super(cls, cls).do_your_stuff()  # WRONG

C.do_your_stuff()

올라갈 것입니다 RuntimeError: maximum recursion depth exceeded while calling a Python object.

만약에 cls ~이다 C, 그 다음에 super(cls, cls) 검색 C.mro() 이후에 오는 수업을 위해 C.

In [161]: C.mro()
Out[161]: [__main__.C, __main__.B, __main__.A, object]

그 수업이기 때문에 B, 언제 cls ~이다 C, super(cls, cls).do_your_stuff() 언제나 전화 B.do_your_stuff. 부터 super(cls, cls).do_your_stuff() 내부로 호출됩니다 B.do_your_stuff, 당신은 결국 전화를받습니다 B.do_your_stuff 무한 루프에서.

python3에서 0- 관점 형태 super 그렇게 추가되었습니다 super(B, cls) 대체 될 수 있습니다 super(), 그리고 python3은 맥락에서 알아낼 것입니다 super() 정의에서 class B 동등해야합니다 super(B, cls).

그러나 어떠한 상황에서도 super(cls, cls) (또는 비슷한 이유로 super(type(self), self)) 정확한.

다른 팁

Python 3에서는 인수 지정을 건너 뛸 수 있습니다. super,

class A:
    @classmethod
    def f(cls):
        return "A's f was called."

class B(A):
    @classmethod
    def f(cls):
        return super().f()

assert B.f() == "A's f was called."

좀 더 명확하게 만들기 위해 기사를 업데이트했습니다. 파이썬 속성 및 방법 # Super

위의 Classmethod를 사용하는 예는 클래스 메소드가 무엇인지를 보여줍니다. 첫 번째 매개 변수로 인스턴스 대신 클래스 자체를 전달합니다. 그러나 예를 들어 메소드를 호출하기 위해 인스턴스가 필요하지 않습니다.

>>> class A(object):
...     @classmethod
...     def foo(cls):
...         print cls
... 
>>> A.foo() # note this is called directly on the class
<class '__main__.A'>

웹 페이지의 예는 게시 된대로 작동하는 것 같습니다. 당신은 만들었습니까? do_something 슈퍼 클래스를위한 방법이지만 클래스 메드로 만들지는 않습니까? 이와 같은 것이 그 오류를 줄 것입니다.

>>> class A(object):
...     def do_something(cls):
...         print cls
... #   do_something = classmethod(do_something)
... 
>>> class B(A):
...     def do_something(cls):
...         super(B, cls).do_something()
...     do_something = classmethod(do_something)
... 
>>> B().do_something()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in do_something
TypeError: unbound method do_something() must be called with B instance as first argument (got nothing instead)

나는이 아름다운 사이트와 사랑스러운 커뮤니티 덕분에 지금 요점을 이해했다고 생각합니다.

당신이 마음에 들지 않으면, 내가 ClassMethods에 틀렸다면 저를 바로 잡으십시오 (지금은 완전히 이해하려고 노력하고 있습니다) :


# EXAMPLE #1
>>> class A(object):
...     def foo(cls):
...             print cls
...     foo = classmethod(foo)
... 
>>> a = A()
>>> a.foo()
# THIS IS THE CLASS ITSELF (__class__)
class '__main__.A'

# EXAMPLE #2
# SAME AS ABOVE (With new @decorator)
>>> class A(object):
...     @classmethod
...     def foo(cls):
...             print cls
... 
>>> a = A()
>>> a.foo()
class '__main__.A'

# EXAMPLE #3
>>> class B(object):
...     def foo(self):
...             print self
... 
>>> b = B()
>>> b.foo()
# THIS IS THE INSTANCE WITH ADDRESS (self)
__main__.B object at 0xb747a8ec
>>>

이 삽화가 보여 주길 바랍니다 ..

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top