Как инициализировать базовый (супер) класс?



в 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, я нашел более одного способа сделать. Каков стандартный способ справиться с этим?

517   4  

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)

https://docs.python.org/3/library/functions.html#super

как инициализировать базовый (супер) класс?

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

    Ничего не найдено.