Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中调用父初始值设定项的链_Python_Oop_Inheritance_Constructor - Fatal编程技术网

python中调用父初始值设定项的链

python中调用父初始值设定项的链,python,oop,inheritance,constructor,Python,Oop,Inheritance,Constructor,考虑这一点-基类a,从a继承的类B,从B继承的类C。在初始化器中调用父类初始化器的一般方法是什么?如果这听起来还是太模糊,这里有一些代码 class A(object): def __init__(self): print "Initialiser A was called" class B(A): def __init__(self): super(B,self).__init__() print "Initialiser B

考虑这一点-基类a,从a继承的类B,从B继承的类C。在初始化器中调用父类初始化器的一般方法是什么?如果这听起来还是太模糊,这里有一些代码

class A(object):
    def __init__(self):
        print "Initialiser A was called"

class B(A):
    def __init__(self):
        super(B,self).__init__()
        print "Initialiser B was called"

class C(B):
    def __init__(self):
        super(C,self).__init__()
        print "Initialiser C was called"

c = C()

我现在就是这样做的。但它似乎仍然有点非泛型-您仍然必须手动传递正确的类型

现在,我尝试使用
self.\uuuuu class\uuuu
作为super()的第一个参数,但是,显然它不起作用-如果你把它放在C的初始化器中-足够公平,B的初始化器就会被调用。如果在B中也这样做,“self”仍然指向C的一个实例,因此您最终再次调用B的初始化器(这以无限递归结束)


现在不需要考虑菱形继承,我只对解决这个特定问题感兴趣。

您这样做的方式确实是推荐的(对于Python2.x)


类是否显式地传递给
super
是一个风格问题,而不是功能问题。将类传递给
super
符合Python“显式优于隐式”的理念。

Python 3包括一个改进的super(),它允许这样使用:

super().__init__(args)

您只需写下:

class A(object):

    def __init__(self):
        print "Initialiser A was called"

class B(A):

    def __init__(self):
        A.__init__(self)
        # A.__init__(self,<parameters>) if you want to call with parameters
        print "Initialiser B was called"

class C(B):

    def __init__(self):
        # A.__init__(self) # if you want to call most super class...
        B.__init__(self)
        print "Initialiser C was called"
A类(对象):
定义初始化(自):
打印“调用初始化器A”
B(A)类:
定义初始化(自):
A.。uuu初始(自我)
#A.。uuu init_uuu(self,)如果要使用参数调用
打印“调用了初始化器B”
丙(乙)类:
定义初始化(自):
#A.uuu init_uuuu(self)#如果你想调用大多数超级类。。。
B.uuu初始(自我)
打印“调用了初始化器C”

“但它似乎仍然有点过于非泛型-您仍然必须手动传递正确的类型。”??您正在将类名传递给super()。你永远不需要知道超类或其他任何东西。这是如何非通用的?这会造成什么问题?你能举一个例子说明这个问题在哪里中断吗?我还没有准备好回答这个问题。但是无论如何,如果这个类被重命名了呢?如果我想编写一个decorator函数来自动化这种链接,该怎么办?现在我明白了,这是不可能的,但在提出这个问题的时候我并不知道。@shylent,如果我理解你的问题,你所描述的是可能的。如果理解mro,可以使用super()使父引用完全通用。谷歌“python super is super”,观看视频。@shylent实际上,再次阅读你的问题,我相信你正在经历的无限递归不是你想象的那样。我相信mro命令会让你打电话给一个你不想打电话的构造器。不久前我自己也处理过同样的事情。无论您将什么传递给super的第一个参数,super都将调用mro中的第一个构造函数,而不是您传入的类型。例如,如果你在C的构造函数中调用super(self.\uuuuu class\uuuuu,self),你仍然会调用B的构造函数,因为它是mro中的第一个父级。我很难决定接受哪个答案,但我会接受这个答案,这仅仅是因为它与我正在使用的python版本相关。在Python2.6中,我得到
TypeError:super()参数1必须是type,而不是classobj
,使用此方法。我遗漏了什么吗?@Leopd:
super()
只适用于新样式的类,即必须从
object
继承。Python是一种强类型语言,但它是动态类型的。弱类型和动态类型之间有区别。@ScienceBoy的定义很清楚。Python具有很强的动态性。Java之类的东西是强静态的。PHP是弱动态的。静态类型保证(至少在某些限制内)输入参数是正确的类型。强类型表示编译器/运行时不会尝试将一种类型的值强制为另一种类型。。比如把“1”改成1,这样你就可以用它来做数学题了。请参见此处:如果我有多个父类,如何超级标识要调用的父类?@kracekumar它将由类的方法解析顺序(MRO)决定,您可以通过调用
MyClassName.MRO()
来了解。我可能不正确,但我相信第一个指定的父级是将调用其
\uuuu init\uuuu
的父级。@ironfroggy,您是否介意详细说明这种改进的超级方法如何帮助解决这个问题?我刚找到这条旧线索,我有同样的问题。自从第一次提出这个问题以来,Python2.x的情况也有了改进吗?@user815423426因为它使up调用更通用,不再重复原始问题的主题类名。@kracekumar,super(x,obj)实际上返回一个特殊的“super”对象,当您对它进行属性访问时,将返回在类X完全没有属性的情况下将返回的属性。例如,super(X,obj)。\uuu init\uuu将返回obj的init方法,就像类X中的init不在那里一样。现在,如果类X有两个父类,并且X._uinit_uuu不存在,那么默认行为是只调用父类之一的init,而不是同时调用父类和父类。这就是super正在做的事情。。。给你一个父母。