Как инициализировать базовый (супер) класс?
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__
via 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')