Как инициализировать базовый (супер) класс?
в Python считать у меня есть следующий код:
>>> class SuperClass(object):
def __init__(self, x):
self.x = x
>>> class SubClass(SuperClass):
def __init__(self, y):
self.y = y
# how do I initialize the SuperClass __init__ here?
как инициализировать SuperClass __init__ в подклассе? Я следую учебнику Python, и он не охватывает это. Когда я искал в Google, я нашел более одного способа сделать. Каков стандартный способ справиться с этим?
4 ответов:
Python (до версии 3) поддерживает классы "старого стиля" и нового стиля. Классы нового стиля являются производными от
objectи то, что вы используете, и вызвать их базовый класс черезsuper(), например,class X(object): def __init__(self, x): pass def doit(self, bar): pass class Y(X): def __init__(self): super(Y, self).__init__(123) def doit(self, foo): return super(Y, self).doit(foo)поскольку python знает о старых и новых классах стиля, существуют различные способы вызова базового метода, поэтому вы нашли несколько способов сделать это.
для полноты картины, классы старого стиля вызывают базовые методы явно используя базовый класс, то есть
def doit(self, foo): return X.doit(self, foo)но так как вы не должны использовать старый стиль больше, я бы не заботился об этом слишком много.
Python 3 знает только о классах нового стиля (независимо от того, производны ли вы от
objectили нет).
и
SuperClass.__init__(self, x)или
super(SubClass,self).__init__( x )будет работать (я предпочитаю 2-й, так как он больше придерживается сухого принципа).
смотрите здесь: http://docs.python.org/reference/datamodel.html#basic-customization
начиная с python 3.5.2, вы можете использовать:
class C(B): def method(self, arg): super().method(arg) # This does the same thing as: # super(C, self).method(arg)
как инициализировать базовый (супер) класс?
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или другой неизменяемый объект.вы можете подумать, что это classmethod, потому что он получает неявный аргумент класса. Но это на самом деле staticmethod. Так что вам нужно позвонить
__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')
Comments