Python 확장-super () Python 3 대 Python 2 사용
원래는 이 질문을 하고 싶었지만 , 이미 생각했던 것 같았습니다 ...
인터넷 검색을 통해 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
Notice how both base classes use super
even though they don't have their own base classes.
What super
does is: it calls the method from the next class in MRO (method resolution order). The MRO for C
is: (C, A, B, object)
. You can print C.__mro__
to see it.
So, C
inherits __init__
from A
and super
in A.__init__
calls B.__init__
(B
follows A
in MRO).
So by doing nothing in C
, you end up calling both, which is what you want.
Now if you were not using super
, you would end up inheriting A.__init__
(as before) but this time there's nothing that would call B.__init__
for you.
class A:
def __init__(self):
print('A')
class B:
def __init__(self):
print('B')
class C(A, B):
pass
C()
#prints:
#A
To fix that you have to define C.__init__
:
class C(A, B):
def __init__(self):
A.__init__(self)
B.__init__(self)
The problem with that is that in more complicated MI trees, __init__
methods of some classes may end up being called more than once whereas super/MRO guarantee that they're called just once.
In short, they are equivalent. Let's have a history view:
(1) at first, the function looks like this.
class MySubClass(MySuperClass):
def __init__(self):
MySuperClass.__init__(self)
(2) to make code more abstract (and more portable). A common method to get Super-Class is invented like:
super(<class>, <instance>)
And init function can be:
class MySubClassBetter(MySuperClass):
def __init__(self):
super(MySubClassBetter, self).__init__()
However requiring an explicit passing of both the class and instance break the DRY (Don't Repeat Yourself) rule a bit.
(3) in V3. It is more smart,
super()
is enough in most case. You can refer to http://www.python.org/dev/peps/pep-3135/
Just to have a simple and complete example for Python 3, which most people seem to be using now.
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)
gives
42
chickenman
Another python3 implementation that involves the use of Abstract classes with super(). You should remember that
super().init(name, 10)
has the same effect as
Person.init(self, name, 10)
Remember there's a hidden 'self' in super(), So the same object passes on to the superclass init method and the attributes are added to the object that called it. Hence super()
gets translated to Person
and then if you include the hidden self, you get the above code frag.
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())
참고URL : https://stackoverflow.com/questions/10482953/python-extending-with-using-super-python-3-vs-python-2
'code' 카테고리의 다른 글
C #에서 Guid를 사용하는 방법? (0) | 2020.09.13 |
---|---|
Android에서 이미지 크기를 조정하는 방법은 무엇입니까? (0) | 2020.09.13 |
C # : 여러 줄 문자열을 통해 반복 (0) | 2020.09.13 |
src 소스 이미지를 찾을 수 없을 때“이미지를 찾을 수 없음”아이콘을 자동으로 숨기는 방법 (0) | 2020.09.13 |
jquery, 쿠키 삭제 (0) | 2020.09.13 |