Как инициализировать базовый (супер) класс?
class SuperClass(object):
def __init__(self, x):
self.x = x
class SubClass(SuperClass):
def __init__(self, y):
self.y = y
Используйте объект super
, чтобы обеспечить получение следующего метода (как связанного метода) впорядок разрешения метода.В Python 2 вам нужно передать имя класса и self
в super для поиска ограниченного метода __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')