Python 使用_init继承属性__
我是Java人,刚刚开始学习Python。举个例子:Python 使用_init继承属性__,python,inheritance,attributes,polymorphism,Python,Inheritance,Attributes,Polymorphism,我是Java人,刚刚开始学习Python。举个例子: class Person(): def __init__(self, name, phone): self.name = name self.phone = phone class Teenager(Person): def __init__(self, name, phone, website): self.name=name self.phone=phone
class Person():
def __init__(self, name, phone):
self.name = name
self.phone = phone
class Teenager(Person):
def __init__(self, name, phone, website):
self.name=name
self.phone=phone
self.website=website
我确信有很多冗余代码(我知道在Java中,上面的代码有很多冗余)
对于已经从父类继承的属性,哪些部分是冗余的 在python中为类编写
\uuuuuu init\uuu
函数时,应始终调用其超类的\uuuu init\uu
函数。我们可以使用它将相关属性直接传递给超类,因此您的代码如下所示:
class Person(object):
def __init__(self, name, phone):
self.name = name
self.phone = phone
class Teenager(Person):
def __init__(self, name, phone, website):
Person.__init__(self, name, phone)
self.website=website
正如其他人所指出的,您可以替换该行
Person.__init__(self, name, phone)
与
代码也会做同样的事情。这是因为在python中,instance.method(args)
只是Class.method(instance,args)
的简写。如果要使用super
,需要确保指定object
作为Person
的基类,就像我在代码中所做的那样
提供了有关如何使用
super
关键字的更多信息。在这种情况下,重要的是它告诉python在self
的超类中查找方法\uuuuu init\uuuu
,该超类不是,python中的属性在构造函数中定义时不会被继承,父类构造函数也不会被调用,除非您手动执行所有操作:
class Person():
def __init__(self, name, phone):
self.name = name
self.phone = phone
class Teenager(Person):
def_init_(self, name, phone, website):
Person.__init__(self, name, phone) # Call parent class constructor.
self.website=website
这里有更多信息:\uuuu init\uuuu
,与java构造函数不同的是,继承层次结构中的每个类都不会自动调用,您需要自己调用
此外,所有对象层次结构都应以对象
为根(特殊情况除外)
您的代码应为:
class Person(object):
def __init__(self, name, phone):
self.name = name
self.phone = phone
class Teenager(Person):
def_init_(self, name, phone, website):
super(Teenager, self).__init__(name, phone)
self.website=website
super
为其第二个参数(self
)创建一个委托,该委托将调用函数列表中的下一个函数来调用每个名称(“方法解析顺序”)。这与在Java中调用超类方法不同
您也可以编写super(type(self),self)。\uuuu init\uuuu(name,phone)
,但是如果您从这个类继承得更远,type(self)
可能不是tender
,并且您可以有一个无限递归。这是一个实际的结果,因为您使用的是具有不同MRO的委托对象,而不是直接调用超类构造函数。我喜欢这样做的方式稍微简洁一些:
class Teenager(Person):
def __init__(self, *args, **kwargs):
self.website=kwargs.pop('website')
super(Teenager, self).__init__(*args, **kwargs)
在这种情况下,这没有多大区别,但是当您有一个带有大量参数的\uuu init\uuu
时,它会使生活变得更简单。到目前为止,所有的示例都是针对Python2.x的,但这里有一个针对Python3.x的解决方案,它使用了较短版本的super(),并且不从对象继承
class Person:
def __init__(self, name, phone):
self.name = name
self.phone = phone
class Teenager(Person):
def __init__(self, name, phone, website):
super().__init__(name, phone)
self.website = website
请注意,如果您使用的是Python2.x,则必须明确地将对象
列为Person
的基类,以便使用super()
。否则,您必须使用Person.\uuuu init\uuu
表单。@chepner您能提供一个参考吗?我找不到。指示仅在新样式的类上支持super(),在Python 2.x中,这些类是从对象继承的类。我没有意识到python类不会像Java中那样自动从公共基类继承。我已经修复了我的代码。投票赞成使用*args和**kwargs(…在参数众多的情况下非常有效)。使用args
和kwargs
通常会导致不一致的行为。明确地从kwargs
中获取关键字意味着a',b',c')
将无法正常工作。它失败并出现一个键错误,因为在本例中,网站
是参数[2]
。
class Person:
def __init__(self, name, phone):
self.name = name
self.phone = phone
class Teenager(Person):
def __init__(self, name, phone, website):
super().__init__(name, phone)
self.website = website