source

Super() Python 3과 Python 2를 사용하여 확장하는 Python

ittop 2023. 7. 21. 21:57
반응형

Super() Python 3과 Python 2를 사용하여 확장하는 Python

원래는 질문을 하고 싶었지만, 그 질문이 이미 전에 생각났다는 것을 알았습니다.

검색해보니 구성 파서를 확장한 예가 있습니다.다음은 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

그리고 나서 파이썬 뉴 클래스와 비교해서 조금 읽었습니다.이전 클래스 스타일(: 여기).그리고 지금 저는 제가 할 수 있는지 궁금합니다.

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"""

근데 전화해야 되는 거 아니에요?이것이 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() (인수 없음)은 (와 함께) 파이썬 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가능하다면, 제가 그 이유를 설명하겠습니다.하지만 항상 할 수 있는 것은 아닙니다.문제는 모든 기본 클래스(및 해당 기본 클래스도 전체 트리)도 사용해야 한다는 것입니다.

만약 그렇다면, 이것도 올바르게 작동할 것입니다. (파이썬 3에서는 하지만 파이썬 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(메소드 해상도 순서)의 다음 클래스에서 메소드를 호출합니다.다음에 대한 MROC다음과 같습니다.(C, A, B, object)인쇄할 수 있습니다.C.__mro__그것을 보기 위해.

그렇게,C상속받은__init__부터A그리고.superA.__init__호출들B.__init__(B뒤따르는AMRO에서).

그래서 아무것도 하지 않음으로써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__일부 클래스의 메서드는 두 번 이상 호출될 수 있지만 슈퍼/MRO는 한 번만 호출되도록 보장합니다.

간단히 말해서, 그들은 동등합니다.기록 보기를 보겠습니다.

처음에, 그 기능은 이렇게 보입니다.

    class MySubClass(MySuperClass):
        def __init__(self):
            MySuperClass.__init__(self)

코드를 더 추상적으로(그리고 더 휴대하기 쉽게) 만듭니다.Super-Class를 얻는 일반적인 방법은 다음과 같습니다.

    super(<class>, <instance>)

그리고 init 함수는 다음과 같습니다.

    class MySubClassBetter(MySuperClass):
        def __init__(self):
            super(MySubClassBetter, self).__init__()

그러나 클래스와 인스턴스를 모두 명시적으로 전달해야 하는 경우 DRY(반복하지 않음) 규칙을 약간 위반합니다.

V3에서.그것은 더 똑똑합니다.

    super()

대부분의 경우 충분합니다.http://www.python.org/dev/peps/pep-3135/ 를 참조할 수 있습니다.

대부분의 사람들이 현재 사용하고 있는 것처럼 보이는 파이썬 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()와 함께 추상 클래스를 사용하는 또 다른 python3 구현입니다.당신은 그것을 기억해야 합니다.

super().__init__(name, 10)

와 동일한 효과가 있습니다.

Person.__init__(self, name, 10)

super()에 숨겨진 'self'가 있다는 것을 기억하십시오. 따라서 동일한 객체가 superclass 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())

언급URL : https://stackoverflow.com/questions/10482953/python-extending-with-using-super-python-3-vs-python-2

반응형