简体   繁体   English

Python:继承超类__init__

[英]Python: Inherit the superclass __init__

I have a base class with a lot of __init__ arguments:我有一个带有很多__init__ arguments 的基础 class:

class BaseClass(object):
    def __init__(self, a, b, c, d, e, f, ...):
        self._a=a+b
        self._b=b if b else a
        ...

All the inheriting classes should run __init__ method of the base class.所有继承类都应该运行基础 class 的__init__方法。

I can write a __init__() method in each of the inheriting classes that would call the superclass __init__ , but that would be a serious code duplication:我可以在每个调用超类__init__的继承类中编写一个__init__()方法,但这将是一个严重的代码重复:

class A(BaseClass):
    def __init__(self, a, b, c, d, e, f, ...):
        super(A, self).__init__(a, b, c, d, e, f, ...)

class B(BaseClass):
    def __init__(self, a, b, c, d, e, f, ...):
        super(A, self).__init__(a, b, c, d, e, f, ...)

class C(BaseClass):
    def __init__(self, a, b, c, d, e, f, ...):
        super(A, self).__init__(a, b, c, d, e, f, ...)

...

What's the most Pythonic way to automatically call the superclass __init__ ?自动调用超类__init__的最 Pythonic 方式是什么?

super(SubClass, self).__init__(...)

Consider using *args and **kw if it helps solving your variable nightmare.如果它有助于解决您的变量噩梦,请考虑使用 *args 和 **kw。

You have to write it explicitly, but on the other hand, if you have lots of args, you should probably use *args for positional args and **kwargs for keyword args.您必须明确地编写它,但另一方面,如果您有很多 args,您可能应该使用 *args 来表示位置 args 和 **kwargs 来表示关键字 args。

class SubClass(BaseClass):
    def __init__(self, *args, **kwargs):
        super(SubClass, self).__init__(*args, **kwargs)
        # SubClass initialization code

Another technique you could use is to minimize the code in init and then at the end of init function, call another custom function.您可以使用的另一种技术是最小化init中的代码,然后在init function 结束时,调用另一个自定义 function。 Then in the subclass, you just need to override the custom function然后在子类中,只需要重写自定义的function

class BaseClass(object):
    def __init__(self, *args, **kwargs):
        # initialization code
        self._a = kwargs.get('a')
        ...
        # custom code for subclass to override
        self.load()

    def load():
        pass

class SubClass(BaseClass)
    def load():
        # SubClass initialization code
        ...

If the derived classes don't implement anything beyond what the base class __init__() already does, just omit the derived classes __init__() methods - the base class __init__() is then called automatically.如果派生类没有实现超出基本 class __init__()已经做的任何事情,只需省略派生类__init__()方法 - 然后自动调用基本 class __init__()方法。

If, OTOH, your derived classes add some extra work in their __init__() , and you don't want them to explicitly call their base class __init__() , you can do this: OTOH,如果您的派生类在它们的__init__()中添加了一些额外的工作,并且您不希望它们显式调用它们的基础 class __init__() ,您可以这样做:

class BaseClass(object):
    def __new__(cls, a, b, c, d, e, f, ...):
        new = object.__new__(cls)
        new._a=a+b
        new._b=b if b else a
        ...
        return new

class A(BaseClass):
    ''' no __init__() at all here '''

class B(BaseClass):
    def __init__(self, a, b, c, d, e, f, ...):
        ''' do stuff with init params specific to B objects '''

Since __new__() is always called automatically, no further work is required in the derived classes.由于__new__()总是自动调用,因此派生类中不需要进一步的工作。

Unless you are doing something useful in the subclass __init__() methods, you don't have to override it.除非您在子类__init__()方法中做一些有用的事情,否则您不必重写它。

def BaseClass(object):
    def __init__(self, a, b, c, d, e, f, ...):
        self._a=a+b
        self._b=b if b else a
        ...

def A(BaseClass):
    def some_other_method(self):
        pass

def B(BaseClass):
    pass

Perhaps a clearer implementation for your case is using **kwargs combined with new added arguments in your derived class as in:对于您的情况,也许更清晰的实现是在派生的 class 中使用 **kwargs与新添加的 arguments 相结合,如下所示:

class Parent:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c


class Child(Parent):
    def __init__(self, d, **kwargs):
        super(Child, self).__init__(**kwargs)
        self.d = d

By this method you avoid the code duplication but preserve the implicit addition of arguments in your derived class.通过这种方法,您可以避免代码重复,但保留在派生的 class 中隐式添加 arguments。

In 2.6 and lower version to inherit init from base class, there is no super function, You can inherit below way:在 2.6 及更低版本中从基础 class 继承 init,没有超级 function,您可以通过以下方式继承:

class NewClass():
     def __init__():
         BaseClass.__init__(self, *args)

Adding a Pythonic implementation.添加 Pythonic 实现。 Assuming you want all attributes passed in, you can use the code below.假设您想要传入所有属性,您可以使用下面的代码。 (Can also keep/remove specific kwargs keys if you want a subset). (如果你想要一个子集,也可以保留/删除特定的 kwargs 键)。

def A(BaseClass):
    def __init__(self, *args, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

base = BaseClass(...)
new = A( **base.__dict__ )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM