2015-07-30 3 views
2

Я прочитал документацию на python, но у меня все еще есть вопросы о наследовании.Как правильно обрабатывать наследование python

  • В старых версиях python вы можете передавать аргументы супер, но больше не нужно. Что делать, если SuperClass выполняет какую-то настройку с использованием своих аргументов?
  • Если унаследовано от объекта, я должен назвать супер? Насколько я могу судить, это не делает функциональной разницы.
  • Работает ли это по-разному в python 2.7 vs. 3.x?

Разве это так, как предполагается наследование?

class SuperClass(object): 
    def __init__(self, super_argument): 
     super(object, self).__init__() 
     self.super_argument = super_argument 
     self.foo() 

class ChildClass(SuperClass): 
    def __init__(self, super_argument): 
     self.super_argument = super_argument 
     super(SuperClass, self).__init__() 

Если да, то делает ли это неработоспособным дизайн для класса, который может быть унаследован?

class SuperClass(object): 
    def __init__(self, super_argument): 
     super(object, self).__init__() 
     self.foo(super_argument) # Argument passed instead without saving in self 
+0

* «передать аргументы супер» * - вы имеете в виду 'супер (здесь) .method()' или 'super(). Method (here)'? – jonrsharpe

+0

'super (SuperClass, self) .__ init __ (super_argument)' или 'super (SuperClass, self, super_argument) .__ init __()' –

+0

Это немного бесполезно, потому что то, что вы там сделали, включает в себя оба набора аргументов, а не укажите *, о которых вы спрашиваете! * Вы можете оставить «SuperClass, self», если вы пишете * только * для 3.x, но 'super_argument' по-прежнему используется по-прежнему. – jonrsharpe

ответ

4

Кажется, в более старых версиях Python вы можете передать аргументы супер, но не более. Что делать, если SuperClass выполняет какую-то настройку с использованием своих аргументов?

Я думаю, вы неправильно поняли, какие аргументы вы можете оставить в 3.x. В Python 2.x, вы необходимо передать аргументы super, чтобы получить корректно связанный метод:

class MyClass(...): 

    def __init__(self, ...): 
     super(MyClass, self).__init__(...) 
      #^these arguments  ^not these 

В 3.x, вы не требуется поставить эти аргументы, вы можете просто позвоните по номеру super().method(...), но он примет их в порядке.

Это то же самое, что и поведение с унаследованием object - вы должны сделать это, чтобы получить класс нового стиля в 2.x, но 3.x создаст класс нового стиля независимо от того, явно ли вы наследуете object.


В любом случае, вы можете передать аргументы метода на super. Так что, если вы пишете только для 3.x, вы могли бы сделать что-то вроде:

class MyClass(SuperClass): 

    def __init__(self, super_arg, my_arg): 
     super().__init__(super_arg) 
      #^don't need these 
         #^still need these 
     self.my_arg = my_arg 

Если наследование от объекта, я должен назвать супер?

Да, потому что вы можете участвовать в множественном наследовании. Сравните:

>>> class SuperClass1(object): 
    def __init__(self): 
     print("SuperClass1.__init__") 


>>> class SuperClass2(object): 
    def __init__(self): 
     print("SuperClass2.__init__") 


>>> class MyClass(SuperClass1, SuperClass2): 
    def __init__(self): 
     print("MyClass.__init__") 
     super(MyClass, self).__init__() 


>>> MyClass() 
MyClass.__init__ 
SuperClass1.__init__ 
<__main__.MyClass object at 0x02D0CC50> 

с:

>>> class SuperClass1(object): 
    def __init__(self): 
     print("SuperClass1.__init__") 
     super(SuperClass1, self).__init__() 


>>> class SuperClass2(object): 
    def __init__(self): 
     print("SuperClass2.__init__") 
     super(SuperClass2, self).__init__() 


>>> class MyClass(SuperClass1, SuperClass2): 
    def __init__(self): 
     print("MyClass.__init__") 
     super(MyClass, self).__init__() 


>>> MyClass() 
MyClass.__init__ 
SuperClass1.__init__ 
SuperClass2.__init__ 
<__main__.MyClass object at 0x02BCDC10> 

В первом, потому что SuperClass1 не вызывает super, SuperClass2.__init__ никогда не будет достигнута.


ли это обрабатывается по-разному в Python 2.7 против 3.x?

Надеюсь, теперь это ясно, - вы должны быть более четко 2.x (или, если вы пишете код, который должен работать в обеих версиях), но в остальном функциональность идентична, и вы должны позвонить super в все уровни в обоих.

+0

Что делает первый SuperClass2? Разве вторая не перезаписывает первую? –

+0

В вашем втором примере (один после «с:»), похоже, вы дважды определяете SuperClass2. Это опечатка? –

+0

Хорошо, тогда спасибо. Теперь я прекрасно понимаю. Меня в основном путали различия между старым и новым стилем классов. Немного не по теме, но чтобы убедиться, что я правильно понимаю, во время множественного наследования классов, класс слева создает экземпляр вправо? Означает ли это, что в дальнейшем список аргументов будет перезаписывать методы более ранних, если они имеют одно и то же имя? –

Смежные вопросы