[英]How do I initialize the base (super) class?
In Python, consider I have the following code:在 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?
How do I initialize the SuperClass __init__
in the subclass?如何在子类中初始化
SuperClass __init__
? I am following the Python tutorial and it doesn't cover that.我正在关注 Python 教程,但它没有涵盖这一点。 When I searched on Google, I found more than one way of doing.
当我在 Google 上搜索时,我找到了不止一种方法。 What is the standard way of handling this?
处理这个问题的标准方法是什么?
Python (until version 3) supports "old-style" and new-style classes. Python(直到版本 3)支持“旧式”和新式类。 New-style classes are derived from
object
and are what you are using, and invoke their base class through super()
, eg新式类派生自
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)
Because python knows about old- and new-style classes, there are different ways to invoke a base method, which is why you've found multiple ways of doing so.因为 python 知道旧式和新式类,所以有不同的方法来调用基方法,这就是为什么你找到了多种方法来这样做。
For completeness sake, old-style classes call base methods explicitly using the base class, ie为了完整起见,旧式类使用基类显式调用基方法,即
def doit(self, foo):
return X.doit(self, foo)
But since you shouldn't be using old-style anymore, I wouldn't care about this too much.但既然你不应该再使用旧式了,我也不会太在意这个。
Python 3 only knows about new-style classes (no matter if you derive from object
or not). Python 3 只知道新式类(无论是否从
object
派生)。
Both两个都
SuperClass.__init__(self, x)
or或者
super(SubClass,self).__init__( x )
will work (I prefer the 2nd one, as it adheres more to the DRY principle).会起作用(我更喜欢第二个,因为它更符合 DRY 原则)。
See here: http://docs.python.org/reference/datamodel.html#basic-customization请参阅此处: http : //docs.python.org/reference/datamodel.html#basic-customization
As of python 3.5.2, you can use:从 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 https://docs.python.org/3/library/functions.html#super
How do I initialize the base (super) class?
如何初始化基(超级)类?
class SuperClass(object): def __init__(self, x): self.x = x class SubClass(SuperClass): def __init__(self, y): self.y = y
Use a super
object to ensure you get the next method (as a bound method) in the method resolution order.使用
super
对象来确保您获得方法解析顺序中的下一个方法(作为绑定方法)。 In Python 2, you need to pass the class name and self
to super to lookup the bound __init__
method:在 Python 2 中,您需要将类名和
self
传递给 super 以查找绑定的__init__
方法:
class SubClass(SuperClass):
def __init__(self, y):
super(SubClass, self).__init__('x')
self.y = y
In Python 3, there's a little magic that makes the arguments to super
unnecessary - and as a side benefit it works a little faster:在 Python 3 中,有一个小魔法使
super
的参数变得不必要 - 作为一个附带好处,它的运行速度要快一些:
class SubClass(SuperClass):
def __init__(self, y):
super().__init__('x')
self.y = y
Hardcoding the parent like this below prevents you from using cooperative multiple inheritance:像下面这样对父级进行硬编码可以防止您使用协作多重继承:
class SubClass(SuperClass):
def __init__(self, y):
SuperClass.__init__(self, 'x') # don't do this
self.y = y
Note that __init__
may only return None
- it is intended to modify the object in-place.请注意,
__init__
可能只返回None
- 它旨在就地修改对象。
__new__
__new__
There's another way to initialize instances - and it's the only way for subclasses of immutable types in Python.还有另一种初始化实例的方法——它是 Python 中不可变类型的子类的唯一方法。 So it's required if you want to subclass
str
or tuple
or another immutable object.因此,如果您想对
str
或tuple
或其他不可变对象进行子类化,则需要它。
You might think it's a classmethod because it gets an implicit class argument.你可能认为它是一个类方法,因为它有一个隐式的类参数。 But it's actually a staticmethod .
但它实际上是一个静态方法。 So you need to call
__new__
with cls
explicitly.所以你需要明确地用
cls
调用__new__
。
We usually return the instance from __new__
, so if you do, you also need to call your base's __new__
via super
as well in your base class.我们通常从
__new__
返回实例,因此如果您这样做,您还需要在基类中通过super
调用基类的__new__
。 So if you use both methods:因此,如果您同时使用这两种方法:
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 sidesteps a little of the weirdness of the super calls caused by __new__
being a static method, but you still need to pass cls
to the non-bound __new__
method: 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')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.