python继承类中的__init__方法

问题描述:

我想给女儿类一些额外的属性,而不必显式调用一个新的方法。那么有没有办法给继承的类__init__类型的方法,不覆盖父类的方法__init__python继承类中的__init__方法

我已经编写了下面的代码,纯粹是为了说明我的问题(因此属性等命名不佳)。

class initialclass(): 
    def __init__(self): 
     self.attr1 = 'one' 
     self.attr2 = 'two'  

class inheritedclass(initialclass): 
    def __new__(self): 
     self.attr3 = 'three' 

    def somemethod(self): 
     print 'the method' 


a = inheritedclass() 

for each in a.__dict__: 
    print each 

#I would like the output to be: 
attr1 
attr2 
attr3 

谢谢

+0

调用'initialclass在派生类的构造函数.__ init__'。但是,'attrX'的顺序不能保证。 – khachik 2011-04-12 14:02:16

+0

*不要*覆盖'__new__',除非你确切地知道它做了什么,为什么你需要摆弄它。你可能不知道。这不是'__init__'的另一个名字。它比我们通常关心的三级更具魔力,特别是初学者。 – delnan 2011-04-12 14:05:40

+0

请注意,'__new__'的参数是'self'的_class_,而不是'self',因为它是一个隐式类方法。所以在你的例子中,你实际上按照你的想法设置了class属性'inheritedclass.attr3',而不是'self.attr3'。 – 2011-04-12 14:06:01

据我知道这是不可能的,但是你可以调用父类的init方法,像这样:

class inheritedclass(initialclass): 
    def __init__(self): 
     initialclass.__init__(self) 
     self.attr3 = 'three' 
+2

辉煌,一直试图找出处理这种情况一段时间的好方法 – qwwqwwq 2013-07-24 22:21:55

__init__使用super只要致电:

class inheritedclass(initialclass): 
    def __new__(self): 
     self.attr3 = 'three' 
     super(initialclass, self).__init__() 

我强烈建议遵循Python的命名约定,并开始一类用大写字母,例如InheritedClassInitialClass。这有助于快速区分类和方法和变量。

+2

具体而言,使用'super(DerivingClass,self).__ init __()'。或者只是在Python 3中使用'super().__ init __()'编辑:-1,因为1.'super'需要继承(!)类,2.不必要地覆盖'__new__',并且代码现在处于事实不正确(它创建一个**类**属性'attr3')。 – delnan 2011-04-12 14:04:13

+0

这与__new__方法一起工作,但lazyr告诉我(正确)我不应该使用__new__,我认为对于我yexo的正确答案。虽然谢谢! – Anake 2011-04-12 14:18:30

+0

@Anake Credit在信用到期的时候,@delnan告诉你不要使用'__new__',我刚刚解释了你的代码实际上做了什么。顺便说一句,'__new__' **必须返回它的类的一个实例,如果你实现它。在上面的答案和你的代码中,'inheritedclass()是None'!换句话说,它根本不起作用。 (我错误地给了这个答案upvote,没有正确读取代码,现在我不能改变它:() – 2011-04-12 15:08:08

只要打电话从父的init指定的方法,如果它存在:

class initialclass(): 
    def __init__(self): 
     self.attr1 = 'one' 
     self.attr2 = 'two' 
     if hasattr(self, 'init_subclass'): 
      self.init_subclass() 

class inheritedclass(initialclass): 
    def init_subclass(self): 
     self.attr3 = 'three' 
+1

虚拟 - 1.不需要做任何额外的工作,更不用说在父类中使用'hasattr'和额外的方法了,你可以简单地定义一个新的'__init__'来使用'super'调用父'__init__'。 – delnan 2011-04-12 14:12:26

+0

@delnan我知道这个,但问题是“是否有一种方法可以给继承的类提供一个init类型的方法,它不会覆盖父类的init方法”,我提供了这种方法,还有一个额外的好处,就是给出一个入口点从一些其他的子类方法调用_only_子类init – 2011-04-12 14:22:43

+1

这就是为什么它是虚拟的,我知道这是OP所要求的,但OP问:“我如何用锤子来做到这一点?”答案是“你使用螺丝刀“。 – delnan 2011-04-12 14:28:26

这非常简单。定义新的方法并在开始时调用父母的__init__

# assuming a class Base, its __init__ takes one parameter x 

class Derived(Base): 
    def __init__(self, x, y): 
     # whatever initialization is needed so we can say Derived is-a Base 
     super(Derived, self).__init__(x) 
     # now, add whatever makes Derived special - do your own initialization 
     self.y = y 

在Python 3,你没有(因此propably不应该,为简单起见)从object明确继承或类和self传递给super

首先你要混合__init____new__,它们是different things__new__不需要实例(self)作为参数,它需要类(cls)。 至于你的问题的主要部分,你必须做的是使用super来调用超类'__init__

您的代码应该是这样的:

class initialclass(object): 
    def __init__(self): 
     self.attr1 = 'one' 
     self.attr2 = 'two'  

class inheritedclass(initialclass): 
    def __init__(self): 
     self.attr3 = 'three' 
     super(inheritedclass, self).__init__() 
+0

谢谢,我对新方法的错误。我想使用超级,我不断收到此错误:TypeError:super()参数1必须是类型,而不是classobj。 (我复制并粘贴你的代码也是一样的) – Anake 2011-04-12 14:35:15

+1

@Anake:'initialclass'需要继承'object'('class initialclass(object)'),否则它是一种旧式的类,诱导过去的遗迹,应该避免。 – delnan 2011-04-12 14:39:15

+0

aaah,好的,谢谢。 (也感谢vartec更新)。 – Anake 2011-04-12 15:09:52