>  기사  >  백엔드 개발  >  __new__ 및 __init__, Python2의 새로운 스타일 클래스 및 클래식 클래스

__new__ 및 __init__, Python2의 새로운 스타일 클래스 및 클래식 클래스

高洛峰
高洛峰원래의
2016-10-18 09:35:181104검색

python2.x에서는 객체에서 상속받는 클래스를 새로운 스타일 클래스(예: 클래스 A(객체))라고 하고, 객체에서 상속하지 않는 클래스를 클래식 클래스(예: 클래스 A())라고 합니다.

새로운 스타일 클래스와 클래식 클래스의 주요 차이점은 다음과 같습니다.

 1. 새로운 스타일 클래스 객체는 __class__ 속성을 통해 자신만의 유형을 직접 얻을 수 있습니다: type

 2. 상속 검색 순서가 변경되었습니다. 클래식 클래스 다중 상속에서 속성 검색 순서는 먼저 상속 트리의 왼쪽으로 깊숙이 들어간 다음 뒤로 돌아가서 오른쪽(즉, 깊이)을 찾기 시작합니다. -첫 번째 검색); 새 클래스 다중 상속 속성 검색 순서: 먼저 가로로 검색한 다음 위로 이동

예:

클래식 클래스: 검색 순서는 (D,B, A,C)

>>> class A: attr = 1
...
>>> class B(A): pass
...
>>> class C(A): attr = 2
...
>>> class D(B,C): pass
...
>>> x = D()
>>> x.attr
1

새 스타일 클래스 상속 검색 절차는 너비 우선

새 스타일 클래스: 검색 순서는 (D,B,C,A)

>>> class A(object): attr = 1
...
>>> class B(A): pass
...
>>> class C(A): attr = 2
...
>>> class D(B,C): pass
...
>>> x = D()
>>> x.attr
2

 3. 새로운 스타일 클래스 추가 __slots__ 내장 속성을 사용하면 인스턴스 속성 유형을 잠글 수 있습니다. __slots__에 의해 지정된 범위.

4. 새로운 스타일 클래스에는 __getattribute__ 메서드가 추가됩니다.

5. 새로운 스타일 클래스에는 __new__ 메서드가 내장되어 있는 반면, 클래식 클래스에는 __new__ 메서드가 없고 __new__ 메서드만 있습니다. __init__ 메소드

참고: Python 2의 기본 클래스입니다. 클래스의 조상), 객체를 명시적으로 상속할 필요가 없습니다(클래식 클래스의 정의에 따라 클래식 클래스를 작성하고 dir 함수를 사용하여 python2.x 및 3.x 버전에서 각각 확인하세요.

예: class A():

                           lain through (dir(A))

2.x에는 __new__ 메소드가 없지만 3.x에는 있습니다. 🎜>

__new__ 메소드와 __init__의 차이점에 대해 이야기해 보겠습니다.

클래스의 인스턴스를 생성할 때 Python에서 클래스에 __new__ 메소드가 있으면 __new_가 먼저 호출됩니다. _Method, __new__ 메소드는 현재 인스턴스화되고 있는 클래스를 첫 번째 매개변수로 허용합니다. (이 매개변수의 유형은 type이며, 이는 C와 Python 간의 대화형 프로그래밍에서 중요한 역할을 합니다.) 관심이 있으시면 관련 정보를 검색하실 수 있습니다. ), 반환 값은 이번에 생성된 인스턴스이며, 이는 잘 알려진 __init__ 메소드의 첫 번째 매개 변수입니다. 그러면 이 인스턴스를 어떻게 얻을 수 있는지에 대한 질문이 있습니다. ?

참고 사항? __new__ 메서드가 있는 메서드는 객체 클래스의 자손이므로 __new__ 메서드를 직접 재정의하려면(재정의하지 않으면 상위 클래스의 __new__ 메서드를 사용합니다.) 상위 클래스에 인스턴스가 없으면 계속해서 추적합니다. 다음과 같이 객체의 __new__ 메소드 클래스를 호출하여 이 인스턴스를 얻을 수 있습니다(실제로는 기본적으로 Python의 기본 메커니즘과 동일합니다).

class display(object):
    def __init__(self, *args, **kwargs):
        print("init")
    def __new__(cls, *args, **kwargs):
        print("new")
        print(type(cls))
        return object.__new__(cls, *args, **kwargs)   
a=display()
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.

new

init

따라서 다음과 같은 결론을 얻을 수 있습니다.

인스턴스 생성 프로세스에서 __new__ 메서드는 __init__ 메서드보다 먼저 호출되며 첫 번째 매개 변수 유형은

다른 특별한 처리가 필요하지 않다면 object.__new__ 메소드를 사용하여 생성된 인스턴스(즉, self)를 가져올 수 있습니다

그래서 실제로 other의 __new__ 메소드를 사용할 수 있음을 알 수 있습니다. 해당 클래스나 상위 클래스 또는 조상에 __new__ 메서드가 있는 한 이 인스턴스를 얻기 위한 클래스

위 출력은 다음과 같습니다.
class another(object):
    def __new__(cls,*args,**kwargs):
        print("newano")
        return object.__new__(cls, *args, **kwargs)   
class display(object):
    def __init__(self, *args, **kwargs):
        print("init")
    def __new__(cls, *args, **kwargs):
        print("newdis")
        print(type(cls))
        return another.__new__(cls, *args, **kwargs)   
a=display()

우리가 발견한 것은 __new__와 __init__가 이러한 관계를 가지고 있다는 것뿐입니다. __init__은 생산을 위한 원료 자체를 제공합니다(그러나 이 원료의 출처를 보장하지는 않습니다). Material은 위와 마찬가지로 관련되지 않은 다른 클래스를 사용합니다. __new__ 메소드 클래스는 이 인스턴스를 가져오고 __init__는 __new__에서 제공한 원자재를 사용하여 객체를 완성합니다(비록 이러한 원자재가 진짜인지는 알 수 없습니다)
newdis
<class &#39;type&#39;>
newano
init

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.