Python에서 super() 함수 소개 및 사용 방법 공유

4463 단어
먼저 super() 함수의 정의를 살펴보겠습니다.super([type [,object-or-type]])
Return a **proxy object** that delegates method calls to a **parent or sibling** class of type.
프록시 대상을 되돌려줍니다. 이 대상은 첫 번째 매개 변수에 분배된 부류나 동년배 클래스를 호출해서 완성합니다.
parent or sibling class 는 어떻게 결정합니까?
첫 번째 매개변수의mro__속성은 검색의 순서를 결정합니다. super는 MRO(Method Resolution Order)의 다음 클래스를 가리키며 반드시 상위 클래스가 아닙니다.
super() 및 getattr() 모두 사용mro__속성으로 검색 순서를 확인합니다.mro__실제로는 읽기만 하는 원조다.
MRO 중류의 순서는 어떻게 되나요?
실제로 MRO 리스트 자체는 C3의 선형화 처리 기술에 의해 확정된 것이기 때문에 이론적 설명은 여기에 참고할 수 있다. 여기서 원칙만 간단하게 설명한다.
MRO에서 기류는 파생류의 뒤에 영원히 나타난다. 만약에 여러 기류가 있다면 기류의 상대적인 순서는 변하지 않는다.
MRO는 실제로 상속수를 차례차례 훑어본 결과 구조를 가진 나무를 하나의 선형 표로 만들었다. 그래서 이 목록을 따라 계속 올라가면 전체 나무를 반복하지 않고 훑어볼 수 있고 다상속 중인 다이몬드 문제를 해결할 수 있다.
예를 들면 다음과 같습니다.

class Root:
  pass

class A(Root):
  pass

class B(Root):
  pass

class C(A, B):
  pass

print(C.__mro__)

#  :
# (, , , , )


슈퍼 ()가 실제적으로 되돌아오는 것은 에이전트의 슈퍼 대상입니다!
슈퍼 () 구조 방법을 호출할 때, 슈퍼 () 대상만 되돌려주고, 다른 작업은 하지 않습니다.
그리고 이 슈퍼 대상을 방법 호출할 때 발생하는 일은 다음과 같다.
첫 번째 매개변수의 찾기mro__목록의 다음에 이 방법의 클래스를 직접 정의하고 대상을 실례화한 다음에 이 대상의self 변수를 두 번째 매개 변수에 귀속시켜 이 대상을 되돌려줍니다
예를 들면 다음과 같습니다.

class Root:
  def __init__(self):
    print('Root')

class A(Root):
  def __init__(self):
    super().__init__() #  super(A, self).__init__()


A의 구조 방법에서 슈퍼 ()를 호출하여 슈퍼 대상을 얻은 다음에 이 대상에게 init 방법을 호출합니다. 이것은 슈퍼 대상이 A를 검색하는 입니다mro__목록, 첫 번째 정의가 있음init__방법의 종류를 찾았고 루트를 호출했다.init__(self), 여기의self는 슈퍼()의 두 번째 매개 변수로 컴파일러가 자동으로 채운 것이다. 즉 A의 이다init__의 첫 번째 매개변수를 사용하여 대init__방법이 호출된 분배.
주의: 많은 언어의 계승에서 자류는 반드시 부류의 구조 방법을 사용해야 한다. 바로 자류의 대상이 부류의 속성을 채울 수 있도록 하기 위해서이다!부류 대상을 초기화하는 것이 아니라...송이경(신지현).파이썬에서 많이 좋아졌어요. 이른바 부류 구조를 사용하는 방법은 명명백백하게self를 부류에게 전달하는 구조 방법이에요. 제 작은 몸뼈를 이렇게 맡겼어요. 마음대로 하세요.
매개변수 설명

super() -> same as super(__class__, ) #  super 
super(type) -> unbound super object
super(type, obj) -> bound super object; requires isinstance(obj, type)
super(type, type2) -> bound super object; requires issubclass(type2, type)

 Typical use to call a cooperative superclass method:
  class C(B):
    def meth(self, arg):
      super().meth(arg)
  This works for class methods too:
  class C(B):
    @classmethod
    def cmeth(cls, arg):
      super().cmeth(arg)


두 번째 인자를 제공하면 찾은 부류 대상의self가 이 인자에 연결되며, 다음에 이 대상의 방법을 호출할 때 자동으로 은밀하게self를 전달할 수 있습니다.두 번째 매개변수가 객체인 경우 isinstance(obj, type)는 True여야 합니다.두 번째 매개변수가 유형인 경우 issubclass(type2, type)는 True여야 합니다.
두 번째 인자가 전달되지 않으면 되돌아오는 대상은 Unbound입니다. 이 unbound 대상을 호출하는 방법은 Base. 와 같이 첫 번째 인자를 수동으로 전달해야 합니다.int__(self, a, b).
파라미터가 없는 슈퍼 () 는 클래스 정의에만 사용할 수 있습니다. (caller의 두 번째 파라미터에 의존하기 때문에) 컴파일러는 자동으로 현재 정의된 클래스에 따라 파라미터를 채웁니다.즉, 뒤에 있는 모든 슈퍼가 대상을 되돌려주는 방법을 호출할 때 첫 번째 파라미터self는 슈퍼()의 두 번째 파라미터이다.파이톤에서 이른바 방법이란 첫 번째 파라미터가self인 함수이기 때문에 일반적으로 방법을 호출할 때 a.b()는 a를 b()의 첫 번째 파라미터에 은밀하게 부여한다.
super()의 두 가지 일반적인 사용 방법:
단일 상속 중, 슈퍼는 은식으로 부류를 가리키는 데 사용되며, 부류의 이름을 직접 사용하는 다중 상속을 피하고Diamond 문제를 해결한다(TODO)
대상에 대한 이해
사실 나는 파이톤에서 이러한 문법이 대상을 향한 본질을 이해하기 쉽고 자바에서 은밀하게 this를 전달하는 것보다 이해하기 쉽다고 생각한다.
함수란 코드를 받아들여 출력을 되돌려 주는 것이다.이른바 방법이란 함수에 은밀하게 전달되는 매개 변수가 있다는 것이다.그래서 방법은 하나의 코드로 클래스의 모든 실례를 공유하는 것이다. 유일하게 다른 것은 각 실례가 호출될 때 방법에 전달되는this나self가 다르다는 것이다.
구조 방법이 뭘까요?사실도 하나의 실례적인 방법이야. 대상이 생성된 후에만 호출할 수 있으니까Python에서init__방법의 매개 변수는self야.구조 방법을 호출할 때 사실은 이미 대상을 위해 메모리를 분배했다. 구조 방법은 초기화 작용을 했을 뿐이다. 즉, 이 메모리에 초기 값을 부여하는 것이다.
자바에서 소위 정적 변수라고 하는 것은 바로 클래스의 변수이다. 사실은 클래스를 위해 메모리를 분배하고 그 안에 이런 변수가 저장되어 있기 때문에 파이톤의 클래스 대상은 매우 합리적이고 자바보다 직관적이다.정적 방법에 대해 말하자면 대상과 아무런 관계도 없다. 본질은 하나의 독립된 함수이고 클래스 안에 썼을 뿐이다.Python 중의classmethod도 정적 방법이지만 이것은cls대상에 의존한다. 이cls는 클래스대상이다. 그러나 이 방법을 사용하려면 클래스대상은 반드시 존재하고 실례대상처럼 수동적인 실례화가 필요하지 않기 때문에classmethod도 정적 변수로 볼 수 있다.staticmethod는 진정한 정적 방법으로 독립된 함수이며 어떠한 대상에도 의존하지 않는다.
자바의 실례적인 방법은 반드시 대상에 의존해야 한다. 왜냐하면 은밀하게 this를 전송해야 하기 때문이다. 만약 대상이 존재하지 않는다면 이this도 은밀하게 전송할 수 없기 때문이다.그래서 정적 방법에this지침이 없으면 실례적인 방법을 사용할 수 없다.Python의 실례적인 방법은 클래스 이름을 통해 호출할 수 있지만 이때self는 은밀하게 전달할 수 없기 때문에 반드시 현저하게 전달해야 한다.

좋은 웹페이지 즐겨찾기