Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.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 __在子调用dict和其他内容时未调用init_Python_Multiple Inheritance_Built In - Fatal编程技术网

Python __在子调用dict和其他内容时未调用init

Python __在子调用dict和其他内容时未调用init,python,multiple-inheritance,built-in,Python,Multiple Inheritance,Built In,考虑以下代码: class Lockable(object): def __init__(self): self._lock = None def is_locked(self): return self._lock is None class LockableDict(dict, Lockable): pass 现在: In [2]: l = example.LockableDict(a=1, b=2, c=3) In [3]

考虑以下代码:

class Lockable(object):

    def __init__(self):
        self._lock = None

    def is_locked(self):
       return self._lock is None


class LockableDict(dict, Lockable):
     pass
现在:

In [2]: l = example.LockableDict(a=1, b=2, c=3)

In [3]: l.is_locked()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-3-4344e3948b9c> in <module>()
----> 1 l.is_locked()

/home/sven/utils/example.py in is_locked(self)
      8 
      9     def is_locked(self):
---> 10         return self._lock is None

AttributeError: 'LockableDict' object has no attribute '_lock'

让它工作。为什么?

从以下评论中可以清楚地看出您的误解:

我不重写
LockableDict
中的
\uuuuuu init\uuuuuu
,所以它应该生成一个
\uuuu init\uuuuuuu
自动调用基类的
\uuuu init\uuuuuuuuu
,不是吗

首先,不会自动生成任何内容;方法解析发生在调用时

在调用时,Python不会调用每个基类的
\uuuu init\uuu
,它只会调用找到的第一个基类*

这就是
super
存在的原因。如果在重写中没有显式调用
super
,则基类甚至同级类都不会调用它们的实现。和
dict.\uuuu init\uuuu
不调用其
super

您的
也不可锁定。\uuuu init\uuuu
。因此,这意味着颠倒顺序可以确保
可锁定。uuuu init_uuu
被调用…但是
dict.uuuu init_uuu
现在不会被调用


那么,你到底想做什么?好的,Python的MRO算法被设计为允许协作类的层次结构具有最大的灵活性,并在最后抛出任何非协作类。所以,你可以这样做:

class Lockable(object):

    def __init__(self):
        super().__init__() # super(Lockable, self).__init__() for 2.x
        self._lock = None

    def is_locked(self):
       return self._lock is None


class LockableDict(Lockable, dict):
     pass
还请注意,这允许您沿着链将初始值设定项参数传递给所有协作类,然后只需使用您知道它需要的参数调用不友好类的
\uuuu init\uuu

在一些情况下,您必须首先放置一个不友好的类。**在这种情况下,您必须显式地调用它们:

class LockableDict(dict, Lockable):
    def __init__(self):
        dict.__init__(self)
        Lockable.__init__(self)
但幸运的是,这种情况并不经常出现


*在标准中,这比您预期的要稍微复杂一些。当您调用
super
查找“下一个”类时,会应用相同的MRO规则,该类可能是基类,也可能是同级,甚至是子类的同级。你可能会发现维基百科上的文章更加平易近人


**特别是对于内置类,因为它们在一些方面很特殊,不值得在这里讨论。同样,许多内置类在其
\uuuuu init\uuuuuu
中实际上不做任何事情,而是在
\uuuu new\uuuuuu
构造函数中进行所有初始化。

您的误解可以从下面的评论中清楚看出:

我不重写
LockableDict
中的
\uuuuuu init\uuuuuu
,所以它应该生成一个
\uuuu init\uuuuuuu
自动调用基类的
\uuuu init\uuuuuuuuu
,不是吗

首先,不会自动生成任何内容;方法解析发生在调用时

在调用时,Python不会调用每个基类的
\uuuu init\uuu
,它只会调用找到的第一个基类*

这就是
super
存在的原因。如果在重写中没有显式调用
super
,则基类甚至同级类都不会调用它们的实现。和
dict.\uuuu init\uuuu
不调用其
super

您的
也不可锁定。\uuuu init\uuuu
。因此,这意味着颠倒顺序可以确保
可锁定。uuuu init_uuu
被调用…但是
dict.uuuu init_uuu
现在不会被调用


那么,你到底想做什么?好的,Python的MRO算法被设计为允许协作类的层次结构具有最大的灵活性,并在最后抛出任何非协作类。所以,你可以这样做:

class Lockable(object):

    def __init__(self):
        super().__init__() # super(Lockable, self).__init__() for 2.x
        self._lock = None

    def is_locked(self):
       return self._lock is None


class LockableDict(Lockable, dict):
     pass
还请注意,这允许您沿着链将初始值设定项参数传递给所有协作类,然后只需使用您知道它需要的参数调用不友好类的
\uuuu init\uuu

在一些情况下,您必须首先放置一个不友好的类。**在这种情况下,您必须显式地调用它们:

class LockableDict(dict, Lockable):
    def __init__(self):
        dict.__init__(self)
        Lockable.__init__(self)
但幸运的是,这种情况并不经常出现


*在标准中,这比您预期的要稍微复杂一些。当您调用
super
查找“下一个”类时,会应用相同的MRO规则,该类可能是基类,也可能是同级,甚至是子类的同级。你可能会发现维基百科上的文章更加平易近人


**特别是对于内置类,因为它们在一些方面很特殊,不值得在这里讨论。同样,许多内置类实际上在它们的
\uuuuuu init\uuuuu
中不做任何事情,而是在
\uuuu new\uuuuuu
构造函数中进行所有初始化。

如果不调用它,就不会调用它。你是什么意思?我不重写
LockableDict
中的
\uuuuuu init\uuuuuu
,所以它应该生成一个
\uuuu init\uuuuuuu
自动调用基类的
\uuuu init\uuuuuuuuu
,不是吗?也不能解释为什么第二个变体工作……你应该在LabababelDistNo的<代码>第二个代码> <代码> >,这是C++的方式,但不是Python。@ RVDK:我认为这是一个不同的问题;这个OP了解Python是如何工作的,并且想知道为什么它是这样设计的;这个人不明白,想知道发生了什么。如果你不叫它,它就不叫。你是什么意思?我不重写
LockableDict
中的
\uuuuuu init\uuuuuu
,所以它应该生成一个
\uuuu init\uuuuuuu
自动调用基类的
\uuuu init\uuuuuuuuu
,不是吗?也不能解释为什么第二个变体工作……你应该在LabababelDistNo的<代码>第二个代码> <代码> >,这是C++的方式,但不是Python。@ RVDK:我认为这是一个不同的问题;这个OP了解Python是如何工作的,并且想知道为什么它是这样设计的;这个人不明白,想知道发生了什么。Python不调用所有的
\uuu init\uuu而只调用它找到的第一个,这有什么好处吗?我没有看到…@Sventimir是的。仅仅有一个好处:想象一下,可锁定是稍后的