В Python 2.x существовало два типа классов:
object
через types.ClassType
object
или другого new-style классаВ Python 3 все классы являются new-style, и концепция old-style классов полностью удалена.
Old-style (Python 2):
class OldClass: # Не наследует от object
pass
New-style (Python 2 и 3):
class NewClass(object): # Явное наследование от object
pass
# В Python 3 все классы автоматически new-style
class ModernClass: # Неявно наследует от object
pass
Old-style:
New-style:
Пример:
# Для old-style классов
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
# Порядок: D → B → A → C → A (дублирование A)
# Для new-style классов
class A(object): pass
class B(A): pass
class C(A): pass
class D(B, C): pass
# Порядок: D → B → C → A (корректный)
Old-style:
__slots__
, дескрипторов, свойствNew-style:
property
, __slots__
, __getattribute__
New-style добавляет:
super()
- улучшенная версия для работы с MRO@classmethod
, @staticmethod
)__new__
, __prepare__
)Old-style:
type(OldClass) # <type 'classobj'>
type(OldClass()) # <type 'instance'>
New-style:
type(NewClass) # <type 'type'>
type(NewClass()) # <class '__main__.NewClass'>
class A:
def __init__(self):
print("A init")
class B(A):
def __init__(self):
print("B init")
A.__init__(self) # Явный вызов - проблема при множественном наследовании
class C(A):
def __init__(self):
print("C init")
A.__init__(self)
class D(B, C):
def __init__(self):
print("D init")
B.__init__(self)
C.__init__(self) # A.__init__ вызывается дважды!
d = D()
class A(object):
def __init__(self):
print("A init")
class B(A):
def __init__(self):
print("B init")
super().__init__() # Автоматически учитывает MRO
class C(A):
def __init__(self):
print("C init")
super().__init__()
class D(B, C):
def __init__(self):
print("D init")
super().__init__() # Вызовет B, затем C, затем A - каждый по одному разу
d = D()
print(D.__mro__) # Показывает порядок разрешения методов
object
super()
Если вы работаете с Python 3, вам не нужно беспокоиться об этом различии - все классы автоматически new-style. Знание этих различий важно для: