왜 파이썬 3.x의 super ()가 마법입니까?
Python 3.x에서는 super()
인수없이 호출 할 수 있습니다.
class A(object):
def x(self):
print("Hey now")
class B(A):
def x(self):
super().x()
>>> B().x()
Hey now
이 일을하기 위해, 일부 컴파일시의 마법은 (리 바인드 다음 코드이다 한 결과 그 중, 수행 super
에가 super_
) 실패
super_ = super
class A(object):
def x(self):
print("No flipping")
class B(A):
def x(self):
super_().x()
>>> B().x()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in x
RuntimeError: super(): __class__ cell not found
super()
컴파일러의 도움없이 런타임에 수퍼 클래스를 확인할 수없는 이유는 무엇 입니까? 이 행동 또는 그에 대한 근본적인 이유가 경고하지 않는 프로그래머를 물 수있는 실제 상황이 있습니까?
... 및 부수적 인 질문 : 파이썬에서 함수, 메소드 등의 다른 예제가 다른 이름으로 리 바인드되어 깨질 수 있습니까?
super()
DRY (Do n't Repeat Yourself) 원칙을 위반하지 않도록 새로운 마법 동작이 추가되었습니다 ( PEP 3135 참조) . 클래스를 전역 클래스로 참조하여 클래스 이름을 명시 적으로 지정해야하는 경우 super()
자체적으로 발견 한 것과 동일한 리 바인딩 문제가 발생하기 쉽습니다 .
class Foo(Bar):
def baz(self):
return super(Foo, self).baz() + 42
Spam = Foo
Foo = something_else()
Spam().baz() # liable to blow up
데코레이터가 클래스 이름을 리 바인드하는 새 객체를 반환하는 클래스 데코레이터 사용에도 동일하게 적용됩니다.
@class_decorator_returning_new_class
class Foo(Bar):
def baz(self):
# Now `Foo` is a *different class*
return super(Foo, self).baz() + 42
매직 super()
__class__
셀은 원래 클래스 객체에 대한 액세스 권한을 부여하여 이러한 문제를 회피합니다.
PEP는 처음 super
에 키워드가 될 것을 구상 한 Guido에 의해 시작되었으며 현재 클래스를 조회하기 위해 셀을 사용한다는 아이디어 도 그의 것이었다 . 확실히, 키워드로 만드는 아이디어 는 PEP 초안의 일부였습니다 .
그러나 실제로 Guido 자신 은 키워드 아이디어에서 '너무 마술 적'을 벗어나 현재 구현을 제안했습니다. 그는 다른 이름을 사용하는 super()
것이 문제가 될 것으로 예상했다 .
내 패치는 중간 솔루션
__class__
을 사용합니다'super'
. 라는 변수를 사용할 때마다 필요하다고 가정합니다 . 따라서 (전역 적으로) 이름super
을 바꾸고supper
사용supper
하지 않지만super
인수가 없으면 작동하지 않습니다 (그러나__class__
실제 클래스 객체 또는 객체 를 전달하면 여전히 작동 합니다). 관련이없는 변수가super
이면 작동하지만 메소드는 셀 변수에 사용되는 약간 느린 호출 경로를 사용합니다.
결국, super
키워드 를 사용하는 것이 옳지 않다고, 마법 __class__
세포 를 제공하는 것이 수용 가능한 타협 이라고 선포 한 것은 귀도 자신 이었습니다.
I agree that the magic, implicit behaviour of the implementation is somewhat surprising, but super()
is one of the most mis-applied functions in the language. Just take a look at all the misapplied super(type(self), self)
or super(self.__class__, self)
invocations found on the Internet; if any of that code was ever called from a derived class you'd end up with an infinite recursion exception. At the very least the simplified super()
call, without arguments, avoids that problem.
As for the renamed super_
; just reference __class__
in your method as well and it'll work again. The cell is created if you reference either the super
or __class__
names in your method:
>>> super_ = super
>>> class A(object):
... def x(self):
... print("No flipping")
...
>>> class B(A):
... def x(self):
... __class__ # just referencing it is enough
... super_().x()
...
>>> B().x()
No flipping
참고URL : https://stackoverflow.com/questions/19608134/why-is-python-3-xs-super-magic
'IT story' 카테고리의 다른 글
Github 풀 요청을 수정하는 방법? (0) | 2020.06.11 |
---|---|
왜 ivar을 사용 하시겠습니까? (0) | 2020.06.11 |
C #에서 이벤트가 발생하는 단위 테스트 (순서대로) (0) | 2020.06.11 |
파이썬 모듈 docstring에 무엇을 넣어야합니까? (0) | 2020.06.11 |
단일 파일 히스토리에서 문자열에 대한 Git 검색 (0) | 2020.06.11 |