Python Can';我不知道我的错:它似乎在调用超类构造函数的某个地方

Python Can';我不知道我的错:它似乎在调用超类构造函数的某个地方,python,python-3.x,Python,Python 3.x,我正在使用Python 3.2.5 我的代码: class Observable: def __init__(self): self.observers = [] ... class View(Frame, Observable): def __init__(self, master=None): super().__init__(View, self) ... 堆栈跟踪: Traceback (most recent call

我正在使用Python 3.2.5

我的代码:

class Observable:
    def __init__(self):
        self.observers = []
   ...

class View(Frame, Observable):

    def __init__(self, master=None):
        super().__init__(View, self)
    ...
堆栈跟踪:

Traceback (most recent call last):
  File "C:\Python34\lib\tkinter\__init__.py", line 108, in _cnfmerge
    for k, v in c.items():
AttributeError: 'View' object has no attribute 'items'

你能帮我理解我做错了什么吗?

你应该直接调用
super()。没有参数的Python3“magic”
super()
与旧的
super(View,self)
相当,因此您不需要将它们作为参数传递。

您只需调用
super()。没有参数的Python3“magic”
super()
与旧的
super(View,self)
相当,因此您不需要将它们作为参数传递。

通常,
items()
与字典一起使用。您正在对
视图
对象调用
items()
方法,从您发布的代码来看,该对象似乎没有实现
items()
。没有定义
items()
方法,也没有子类化
dict

另外,正如其他人已经指出的那样,对
super()
的调用被中断。但我认为即使你把它修好了,你也会有问题的

似乎
视图
应该继承自
框架
,因为这是创建自定义Tkinter小部件的正常方法。Python的MRO将使
super()。这可能会破坏
框架的功能。也许您应该重新考虑您的类设计,或者尝试显式调用框架构造函数

你也应该有这样的信息

_cnfmerge:由于以下原因而导致的回退:foo

请检查/张贴此消息。这可能会有帮助。

通常,
items()
与字典一起使用。您正在对
视图
对象调用
items()
方法,从您发布的代码来看,该对象似乎没有实现
items()
。没有定义
items()
方法,也没有子类化
dict

另外,正如其他人已经指出的那样,对
super()
的调用被中断。但我认为即使你把它修好了,你也会有问题的

似乎
视图
应该继承自
框架
,因为这是创建自定义Tkinter小部件的正常方法。Python的MRO将使
super()。这可能会破坏
框架的功能。也许您应该重新考虑您的类设计,或者尝试显式调用框架构造函数

你也应该有这样的信息

_cnfmerge:由于以下原因而导致的回退:foo


请检查/张贴此消息。这可能会有帮助。

您正在将类
视图
和您的
自我
引用传递到超类
\uuuu init\uu
构造函数中。您似乎混淆了对超级构造函数的两个等价调用:

super().__init__()
super(View, self).__init__()
在这两种情况下,
\uuuu init\uuu
的参数都适合于
self.\uuu init\uuu()
。这就是您收到错误的原因

有关如何调用
super()
的更多信息,请参阅

但是,您还有其他问题。 正如@AndréLaszlo所注意到的,使用
super()。\uuuuu init\uuuu
的问题比
视图中的那一行代码要多

根据,要使用
super()
来处理子类使用多重继承时可以重新排序的方法调用,需要满足某些条件:

  • super()调用的方法必须存在
  • 调用者和被调用者需要有匹配的参数签名
  • 并且每次出现该方法都需要使用super()
第一个条件很简单;所有类都有
\uuuu init\uuuu
。第二个条件可能还可以;您所展示的所有构造函数都可以无参数调用

但是,您打破了发布的代码中的第三个条件:
Observable.\uuu init\uu()
不在其内部调用
super()。\uu init\uu()
。如果你真的想使用这种技术,那就应该加上。(不要忘记,您可以选择在设计中不使用
super()
——您可以始终显式调用超类构造函数。)


那么帧呢?\uuu init\uuuu()
?它是否调用
super()?如果此代码不在您的控制之下,并且它不通过在其构造函数中使用
super()
进行“协作”,那么最安全的解决方案可能是为
Frame
创建一个适配器类,该类包含一个
super()。\uuuu init\uuuu()
调用,根据“如何合并非协作类”部分,您正在将类
视图
和您的
self
引用传递到超类
\uuuu init\uuuu
构造函数中。您似乎混淆了对超级构造函数的两个等价调用:

super().__init__()
super(View, self).__init__()
在这两种情况下,
\uuuu init\uuu
的参数都适合于
self.\uuu init\uuu()
。这就是您收到错误的原因

有关如何调用
super()
的更多信息,请参阅

但是,您还有其他问题。 正如@AndréLaszlo所注意到的,使用
super()。\uuuuu init\uuuu
的问题比
视图中的那一行代码要多

根据,要使用
super()
来处理子类使用多重继承时可以重新排序的方法调用,需要满足某些条件:

  • super()调用的方法必须存在
  • 调用者和被调用者需要有匹配的参数签名
  • 并且每次出现该方法都需要使用super()