如何正确处理python继承

时间:2015-07-30 15:06:20

标签: python inheritance

我已经阅读了python文档,但我仍然对继承有疑问。

  • 似乎在旧版本的python中你可以将参数传递给super,但不再是。如果SuperClass使用其参数进行某种设置会怎么样?
  • 如果从对象继承,我应该打电话给super吗?据我所知,它没有产生功能差异。
  • 这在python 2.7与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

1 个答案:

答案 0 :(得分: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
  

如果继承自object,我应该调用super吗?

是的,因为您可能参与了多重继承。比较:

>>> 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两个层次都在。