Python Can';我不知道我的错:它似乎在调用超类构造函数的某个地方
我正在使用Python 3.2.5 我的代码: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
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()