Як ініціалізувати базовий (супер) клас?
class SuperClass(object):
def __init__(self, x):
self.x = x
class SubClass(SuperClass):
def __init__(self, y):
self.y = y
Використовуйте super
об'єкт, щоб переконатися, що ви отримаєте наступний метод (як зв'язаний метод) у порядку вирішення методу. У Python 2 вам потрібно передати ім'я класу та self
супер шукати пов'язаний __init__
метод:
class SubClass(SuperClass):
def __init__(self, y):
super(SubClass, self).__init__('x')
self.y = y
У Python 3 є маленька магія, яка робить аргументи super
непотрібними - і, як побічна вигода, вона працює трохи швидше:
class SubClass(SuperClass):
def __init__(self, y):
super().__init__('x')
self.y = y
Жорстке кодування вищезгаданого батька перешкоджає використанню кооперативного множинного спадкування:
class SubClass(SuperClass):
def __init__(self, y):
SuperClass.__init__(self, 'x') # don't do this
self.y = y
Зауважте, що __init__
може лише повернутисяNone
- він призначений для зміни об'єкта на місці.
Щось __new__
Є ще один спосіб ініціалізації екземплярів - і це єдиний спосіб для підкласів незмінних типів у Python. Так що це необхідно , якщо ви хочете підклас str
або tuple
або інший незмінний об'єкт.
Ви можете подумати, що це класний метод, оскільки він отримує неявний аргумент класу. Але це насправді статичний метод . Тож вам потрібно зателефонувати __new__
з cls
явно.
Ми, як правило, повертаємо екземпляр __new__
, тому, якщо ви це зробите, вам також потрібно зателефонувати в базу __new__
через super
ваш базовий клас. Тож якщо ви використовуєте обидва способи:
class SuperClass(object):
def __new__(cls, x):
return super(SuperClass, cls).__new__(cls)
def __init__(self, x):
self.x = x
class SubClass(object):
def __new__(cls, y):
return super(SubClass, cls).__new__(cls)
def __init__(self, y):
self.y = y
super(SubClass, self).__init__('x')
Python 3 ухиляється від дивацтва супервикликів, спричинених __new__
статичним методом, але вам все одно потрібно перейти cls
до безмежного __new__
методу:
class SuperClass(object):
def __new__(cls, x):
return super().__new__(cls)
def __init__(self, x):
self.x = x
class SubClass(object):
def __new__(cls, y):
return super().__new__(cls)
def __init__(self, y):
self.y = y
super().__init__('x')