슈퍼 사용법 정확함(잘못된 패싱)
그래서 저는 파이썬의 "유해하다고 생각되는 것"을 따라가서 그의 예를 시험해 보았습니다.
단, 올바른 통화 방법을 보여주어야 하는 예 1-3.super
취급할 때.__init__
서로 다른 주장을 예상하는 방법, 즉 완전한 방식은 효과가 없습니다.
다음과 같은 정보를 얻을 수 있습니다.
~ $ python example1-3.py
MRO: ['E', 'C', 'A', 'D', 'B', 'object']
E arg= 10
C arg= 10
A
D arg= 10
B
Traceback (most recent call last):
File "Download/example1-3.py", line 27, in <module>
E(arg=10)
File "Download/example1-3.py", line 24, in __init__
super(E, self).__init__(arg, *args, **kwargs)
File "Download/example1-3.py", line 14, in __init__
super(C, self).__init__(arg, *args, **kwargs)
File "Download/example1-3.py", line 4, in __init__
super(A, self).__init__(*args, **kwargs)
File "Download/example1-3.py", line 19, in __init__
super(D, self).__init__(arg, *args, **kwargs)
File "Download/example1-3.py", line 9, in __init__
super(B, self).__init__(*args, **kwargs)
TypeError: object.__init__() takes no parameters
는 것 같습니다.object
그 자체는 문서에 언급된 모범 사례 중 하나를 위반합니다. 즉, 다음 방법을 사용합니다.super
수락해야 함*args
그리고.**kwargs
.
자, 분명히 나이트 씨는 자신의 예시가 효과가 있을 것이라고 기대했습니다. 그렇다면 이것이 최근 버전의 파이썬에서 변경된 것일까요?2.6과 2.7을 확인했는데 두 가지 모두 실패했습니다.
그렇다면 이 문제를 다루는 올바른 방법은 무엇일까요?
경우에 따라 두 클래스에 일부 매개 변수 이름이 공통적으로 있을 수 있습니다.이 경우 키-값 쌍을 팝업에서 제거할 수 없습니다.**kwargs
또는 에서 제거합니다.*args
대신 다음을 정의할 수 있습니다.Base
와는 다른 계급object
인수 흡수/제거:
class Base(object):
def __init__(self, *args, **kwargs): pass
class A(Base):
def __init__(self, *args, **kwargs):
print "A"
super(A, self).__init__(*args, **kwargs)
class B(Base):
def __init__(self, *args, **kwargs):
print "B"
super(B, self).__init__(*args, **kwargs)
class C(A):
def __init__(self, arg, *args, **kwargs):
print "C","arg=",arg
super(C, self).__init__(arg, *args, **kwargs)
class D(B):
def __init__(self, arg, *args, **kwargs):
print "D", "arg=",arg
super(D, self).__init__(arg, *args, **kwargs)
class E(C,D):
def __init__(self, arg, *args, **kwargs):
print "E", "arg=",arg
super(E, self).__init__(arg, *args, **kwargs)
print "MRO:", [x.__name__ for x in E.__mro__]
E(10)
수확량
MRO: ['E', 'C', 'A', 'D', 'B', 'Base', 'object']
E arg= 10
C arg= 10
A
D arg= 10
B
이것이 효과가 있으려면,Base
MRO의 끝이 없는 클래스여야 합니다.
상속이 많을 경우(여기에 해당) 모든 매개 변수를 다음과 같이 전달할 것을 제안합니다.**kwargs
,그리고 나서.pop
사용 후 바로 사용할 수 있습니다(상위 클래스에 필요하지 않은 경우).
class First(object):
def __init__(self, *args, **kwargs):
self.first_arg = kwargs.pop('first_arg')
super(First, self).__init__(*args, **kwargs)
class Second(First):
def __init__(self, *args, **kwargs):
self.second_arg = kwargs.pop('second_arg')
super(Second, self).__init__(*args, **kwargs)
class Third(Second):
def __init__(self, *args, **kwargs):
self.third_arg = kwargs.pop('third_arg')
super(Third, self).__init__(*args, **kwargs)
이것이 그러한 문제들을 해결하는 가장 간단한 방법입니다.
third = Third(first_arg=1, second_arg=2, third_arg=3)
슈퍼로 여겨지는 파이썬의 슈퍼()에서 설명했듯이, 한 가지 방법은 클래스가 필요한 인수를 먹고 나머지를 전달하는 것입니다.따라서, 콜 체인이 도달하면object
모든 논쟁은 먹혔고, 그리고.object.__init__
인수 없이 호출됩니다(예상대로).따라서 코드는 다음과 같습니다.
class A(object):
def __init__(self, *args, **kwargs):
print "A"
super(A, self).__init__(*args, **kwargs)
class B(object):
def __init__(self, *args, **kwargs):
print "B"
super(B, self).__init__(*args, **kwargs)
class C(A):
def __init__(self, arg, *args, **kwargs):
print "C","arg=",arg
super(C, self).__init__(*args, **kwargs)
class D(B):
def __init__(self, arg, *args, **kwargs):
print "D", "arg=",arg
super(D, self).__init__(*args, **kwargs)
class E(C,D):
def __init__(self, arg, *args, **kwargs):
print "E", "arg=",arg
super(E, self).__init__(*args, **kwargs)
print "MRO:", [x.__name__ for x in E.__mro__]
E(10, 20, 30)
언급URL : https://stackoverflow.com/questions/8972866/correct-way-to-use-super-argument-passing
'source' 카테고리의 다른 글
부트스트랩 3의 열에서 패딩 제거 (0) | 2023.07.31 |
---|---|
node.js가 설치되었는지 여부를 확인하는 방법 (0) | 2023.07.31 |
오류: 'keytool'이(가) 내부 또는 외부 명령, 작동 가능한 프로그램 또는 배치 파일로 인식되지 않습니다. (0) | 2023.07.31 |
nodejs 연결 오류: "'static' 메서드가 없습니다." (0) | 2023.07.31 |
Express-js 와일드카드 라우팅을 통해 경로를 포함한 모든 항목을 처리합니다. (0) | 2023.07.31 |