파이썬에서 이전 스타일과 새로운 스타일 클래스의 차이점은 무엇입니까? 언제 하나를 사용해야합니까?
답변
에서 새로운 스타일과 클래식 클래스 :
Python 2.1까지, 구식 클래스는 사용자가 사용할 수있는 유일한 특징이었습니다.
(구식) 클래스의 개념은 유형의 개념과 관련이 없습니다
x
. 구식 클래스의 인스턴스 인 경우 클래스를x.__class__
지정x
하지만type(x)
항상<type
입니다.
'instance'>이는 클래스와 관계없이 모든 이전 스타일 인스턴스가 인스턴스라는 단일 내장 유형으로 구현된다는 사실을 반영합니다.
새로운 스타일의 클래스가 Python 2.2에 도입되어 class와 type의 개념을 통합했습니다 . 새로운 스타일의 클래스는 단순히 사용자 정의 유형입니다.
x가 새 스타일 클래스의 인스턴스 인 경우
type(x)
일반적으로 다음과 동일합니다x.__class__
(이는 보장되지 않지만 새 스타일 클래스 인스턴스는에 대해 반환 된 값을 재정의 할 수 있음x.__class__
).새로운 스타일의 클래스를 도입하는 주요 동기는 완전한 메타 모델을 가진 통합 객체 모델을 제공하는 것 입니다.
또한 대부분의 내장 유형을 서브 클래 싱하는 기능이나 계산 된 속성을 가능하게하는 “설명자”의 도입과 같은 많은 즉각적인 이점이 있습니다.
호환성 때문에 클래스는 기본적으로 여전히 구식 입니다.
새 스타일 클래스는 다른 새 스타일 클래스 (예 : 유형)를 부모 클래스로 지정하거나 다른 부모가 필요하지 않은 경우 “최상위 유형”개체로 지정하여 만듭니다.
새 스타일 클래스의 동작은 반환되는 유형 외에 여러 가지 중요한 세부 사항에서 이전 스타일 클래스의 동작과 다릅니다.
이러한 변경 중 일부는 특수 메소드가 호출되는 방식과 같이 새 객체 모델의 기본입니다. 다른 것들은 다중 상속의 경우 메소드 해결 순서와 같이 호환성 문제로 이전에 구현할 수 없었던 “수정”입니다.
파이썬 3에는 새로운 스타일의 클래스 만 있습니다 .
서브 클래스의 유무에 관계없이
object
클래스는 파이썬 3에서 새로운 스타일입니다.
답변
선언 현명한 :
새 스타일 클래스는 object 또는 다른 새 스타일 클래스에서 상속됩니다 .
class NewStyleClass(object):
pass
class AnotherNewStyleClass(NewStyleClass):
pass
구식 수업은 그렇지 않습니다.
class OldStyleClass():
pass
파이썬 3 참고 :
Python 3은 이전 스타일 클래스를 지원하지 않으므로 위에서 언급 한 형식 중 하나가 새로운 스타일 클래스가됩니다.
답변
이전 스타일 클래스와 새로운 스타일 클래스 사이의 중요한 동작 변경
MRO (Method Resolution Order)가 변경되었습니다.
다른 답변에서 언급되었지만 고전 MRO와 C3 MRO (새로운 스타일 클래스에서 사용)의 차이점에 대한 구체적인 예가 있습니다.
문제는 속성 (메소드 및 멤버 변수 포함)이 다중 상속에서 검색되는 순서입니다.
클래식 수업 은 왼쪽에서 오른쪽으로 깊이 우선 검색을 수행합니다. 첫 경기에서 멈춰라. __mro__
속성 이 없습니다 .
class C: i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass
assert C12().i == 0
assert C21().i == 2
try:
C12.__mro__
except AttributeError:
pass
else:
assert False
새로운 스타일의 수업 MRO는 단일 영어 문장으로 합성하기가 더 복잡합니다. 여기 에 자세히 설명되어 있습니다 . 그 속성 중 하나는 기본 클래스가 모든 파생 클래스가 검색된 후에 만 검색된다는 것입니다. __mro__
검색 순서를 표시 하는 속성이 있습니다.
class C(object): i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass
assert C12().i == 2
assert C21().i == 2
assert C12.__mro__ == (C12, C1, C2, C, object)
assert C21.__mro__ == (C21, C2, C1, C, object)
새로운 스타일 클래스 객체는 Exception
파이썬 2.5 주변에서 많은 클래스가 생길 수 있었고 파이썬 2.6 주변에서는이 클래스가 제거되었습니다. 파이썬 2.7.3에서 :
# OK, old:
class Old: pass
try:
raise Old()
except Old:
pass
else:
assert False
# TypeError, new not derived from `Exception`.
class New(object): pass
try:
raise New()
except TypeError:
pass
else:
assert False
# OK, derived from `Exception`.
class New(Exception): pass
try:
raise New()
except New:
pass
else:
assert False
# `'str'` is a new style object, so you can't raise it:
try:
raise 'str'
except TypeError:
pass
else:
assert False
답변
이전 스타일 클래스는 여전히 속성 조회 속도가 약간 빠릅니다. 이것은 일반적으로 중요하지 않지만 성능에 민감한 Python 2.x 코드에서 유용 할 수 있습니다.
[3]에서 : 클래스 A : ... : 데프 __init __ (자체) : ... : self.a = '안녕하세요' ... : [4]에서 : 클래스 B (객체) : ... : 데프 __init __ (자체) : ... : self.a = '안녕하세요' ... : [6]에서 : aobj = A () [7]에서 : bobj = B () [8]에서 : % timeit aobj.a 10000000 루프, 루프 당 3 : 78.7ns [10]에서 : % timeit bobj.a 10000000 루프, 루프 당 3 : 86.9ns
답변
귀도는 파이썬의 새로운 스타일과 구식 클래스에 대한 훌륭한 기사 인 New-Style Classes에 대한 The Inside Story를 작성 했습니다.
파이썬 3에는 새로운 스타일의 클래스 만 있습니다. ‘구식 클래스’를 작성하더라도 묵시적으로 파생됩니다 object
.
새로운 스타일 클래스에는 super
새로운 C3 mro , 일부 마법적인 방법 등과 같은 구식 클래스에서 부족한 몇 가지 고급 기능이 있습니다 .
답변
여기에는 매우 실용적이고 참 / 거짓의 차이가 있습니다. 다음 코드의 두 버전 간의 유일한 차이점은 두 번째 버전에서 Person 이 object 로부터 상속 한다는 것입니다 . 그 외에 두 버전은 동일하지만 결과가 다릅니다.
-
구식 수업
class Person(): _names_cache = {} def __init__(self,name): self.name = name def __new__(cls,name): return cls._names_cache.setdefault(name,object.__new__(cls,name)) ahmed1 = Person("Ahmed") ahmed2 = Person("Ahmed") print ahmed1 is ahmed2 print ahmed1 print ahmed2 >>> False <__main__.Person instance at 0xb74acf8c> <__main__.Person instance at 0xb74ac6cc> >>>
-
새로운 스타일의 수업
class Person(object): _names_cache = {} def __init__(self,name): self.name = name def __new__(cls,name): return cls._names_cache.setdefault(name,object.__new__(cls,name)) ahmed1 = Person("Ahmed") ahmed2 = Person("Ahmed") print ahmed2 is ahmed1 print ahmed1 print ahmed2 >>> True <__main__.Person object at 0xb74ac66c> <__main__.Person object at 0xb74ac66c> >>>
답변
새로운 스타일의 클래스 object
는 파이썬 2.2부터 (예를 들어 class Classname(object):
대신 class Classname:
) 상속 받아야합니다 . 핵심 변경 사항은 형식과 클래스를 통합하는 것이며, 이로 인한 부작용은 기본 제공 형식에서 상속 할 수 있다는 것입니다.
자세한 내용은 descrintro 를 읽으십시오 .