원래는 이 질문을 하고 싶었지만 , 이미 생각했던 것 같았습니다 …
인터넷 검색을 통해 configparser 확장 예제를 찾았습니다 . 다음은 Python 3에서 작동합니다.
$ python3
Python 3.2.3rc2 (default, Mar 21 2012, 06:59:51)
[GCC 4.6.3] on linux2
>>> from configparser import SafeConfigParser
>>> class AmritaConfigParser(SafeConfigParser):
... def __init_(self):
... super().__init__()
...
>>> cfg = AmritaConfigParser()
그러나 Python 2에서는 그렇지 않습니다.
>>> class AmritaConfigParser(SafeConfigParser):
... def __init__(self):
... super(SafeConfigParser).init()
...
>>> cfg = AmritaConfigParser()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
TypeError: must be type, not classob
그런 다음 Python New Class vs. Old Class 스타일에 대해 조금 읽었습니다 (예 : 여기 . 이제 궁금합니다.
class MyConfigParser(ConfigParser.ConfigParser):
def Write(self, fp):
"""override the module's original write funcition"""
....
def MyWrite(self, fp):
"""Define new function and inherit all others"""
하지만 init를 호출하면 안되나요? 이것은 Python 2에서 동등합니까?
class AmritaConfigParser(ConfigParser.SafeConfigParser):
#def __init__(self):
# super().__init__() # Python3 syntax, or rather, new style class syntax ...
#
# is this the equivalent of the above ?
def __init__(self):
ConfigParser.SafeConfigParser.__init__(self)
답변
-
super()
(인수없이) Python 3에서 도입되었습니다 (와 함께__class__
) :super() -> same as super(__class__, self)
새 스타일 클래스에 해당하는 Python 2입니다.
super(CurrentClass, self)
-
구식 클래스의 경우 항상 다음을 사용할 수 있습니다.
class Classname(OldStyleParent): def __init__(self, *args, **kwargs): OldStyleParent.__init__(self, *args, **kwargs)
답변
단일 상속의 경우 (한 클래스 만 하위 클래스로 지정하는 경우) 새 클래스는 기본 클래스의 메서드를 상속합니다. 여기에는 __init__
. 따라서 클래스에서 정의하지 않으면 기본에서 가져옵니다.
다중 상속을 도입하면 상황이 복잡해지기 시작합니다 (한 번에 둘 이상의 클래스를 서브 클래 싱). 이는 둘 이상의 기본 클래스에가있는 __init__
경우 클래스가 첫 번째 클래스 만 상속하기 때문입니다.
그런 경우에는 할 수 있으면 정말 써야 super
하는데 그 이유를 설명하겠습니다. 하지만 항상 그런 것은 아닙니다. 문제는 모든 기본 클래스가이를 사용해야한다는 것입니다 (그리고 기본 클래스도 전체 트리).
이 경우에도 올바르게 작동합니다 (Python 3에서하지만 Python 2로 재 작업 할 수 있습니다. 또한 super
) :
class A:
def __init__(self):
print('A')
super().__init__()
class B:
def __init__(self):
print('B')
super().__init__()
class C(A, B):
pass
C()
#prints:
#A
#B
super
자체 기본 클래스가 없더라도 두 기본 클래스가 어떻게 사용되는지 확인하십시오 .
어떤 super
일은이다 : 그것은 MRO의 다음 클래스의 방법 (방법 확인 순서)를 호출합니다. 의 MRO C
: (C, A, B, object)
. 인쇄 C.__mro__
하여 볼 수 있습니다 .
따라서, C
상속 __init__
에서 A
와 super
의 A.__init__
통화 B.__init__
( B
다음 A
MRO에).
따라서에서 아무것도하지 C
않으면 결국 둘 다 호출하게됩니다.
이제를 사용하지 않으면 이전과 마찬가지로 super
상속하게 A.__init__
되지만 이번에는 호출 B.__init__
할 항목이 없습니다.
class A:
def __init__(self):
print('A')
class B:
def __init__(self):
print('B')
class C(A, B):
pass
C()
#prints:
#A
이를 수정하려면 다음을 정의해야합니다 C.__init__
.
class C(A, B):
def __init__(self):
A.__init__(self)
B.__init__(self)
문제는 더 복잡한 MI 트리에서는 __init__
일부 클래스의 메서드가 두 번 이상 호출 될 수있는 반면 super / MRO는 해당 메서드가 한 번만 호출되도록 보장한다는 것입니다.
답변
간단히 말해 동등합니다. 히스토리 뷰를 보겠습니다.
(1) 처음에는 함수가 이렇게 생겼습니다.
class MySubClass(MySuperClass):
def __init__(self):
MySuperClass.__init__(self)
(2) 코드를보다 추상적이고 이식 가능하게 만들기 위해. Super-Class를 얻는 일반적인 방법은 다음과 같이 발명되었습니다.
super(<class>, <instance>)
초기화 함수는 다음과 같습니다.
class MySubClassBetter(MySuperClass):
def __init__(self):
super(MySubClassBetter, self).__init__()
그러나 클래스와 인스턴스의 명시 적 전달을 요구하면 DRY (Do n’t Repeat Yourself) 규칙이 약간 어긋납니다.
(3) V3에서. 더 똑똑하고
super()
대부분의 경우 충분합니다. http://www.python.org/dev/peps/pep-3135/를 참조 할 수 있습니다 .
답변
대부분의 사람들이 지금 사용하고있는 것처럼 보이는 Python 3에 대한 간단하고 완전한 예제를 가지려고합니다.
class MySuper(object):
def __init__(self,a):
self.a = a
class MySub(MySuper):
def __init__(self,a,b):
self.b = b
super().__init__(a)
my_sub = MySub(42,'chickenman')
print(my_sub.a)
print(my_sub.b)
준다
42
chickenman
답변
super ()와 함께 Abstract 클래스를 사용하는 또 다른 python3 구현입니다. 당신은 그것을 기억해야합니다
super().__init__(name, 10)
다음과 같은 효과가 있습니다.
Person.__init__(self, name, 10)
super ()에는 숨겨진 ‘self’가 있으므로 동일한 객체가 수퍼 클래스 init 메서드로 전달되고 속성이이를 호출 한 객체에 추가됩니다. 따라서 super()
로 번역되고 Person
숨겨진 자아를 포함하면 위의 코드 조각이 나타납니다.
from abc import ABCMeta, abstractmethod
class Person(metaclass=ABCMeta):
name = ""
age = 0
def __init__(self, personName, personAge):
self.name = personName
self.age = personAge
@abstractmethod
def showName(self):
pass
@abstractmethod
def showAge(self):
pass
class Man(Person):
def __init__(self, name, height):
self.height = height
# Person.__init__(self, name, 10)
super().__init__(name, 10) # same as Person.__init__(self, name, 10)
# basically used to call the superclass init . This is used incase you want to call subclass init
# and then also call superclass's init.
# Since there's a hidden self in the super's parameters, when it's is called,
# the superclasses attributes are a part of the same object that was sent out in the super() method
def showIdentity(self):
return self.name, self.age, self.height
def showName(self):
pass
def showAge(self):
pass
a = Man("piyush", "179")
print(a.showIdentity())