python - 继承自 Tkinter.Canvas - 调用 super 会导致错误

标签 python inheritance canvas tkinter super

我想问一个关于使用 Canvas 作为容器的聪明问题,但是在编写我的示例代码时我偶然发现了一些奇怪的东西。这是到目前为止的代码:

import Tkinter as tk

class CCanvas(tk.Canvas):

    def __init__(self,master,*args,**kwargs):
        super(CCanvas,self).__init__(master=master,*args,**kwargs)


if __name__ == '__main__':
    root= tk.Tk()
    cc = CCanvas(root)
    cc.pack()
    root.mainloop()

现在这段代码应该做的不多了。 CCanvas类只是继承自Canvas,没有实现任何东西,只是调用父类(super class)的构造函数。我看不出任何不起作用的理由。 然而,当我运行它时,出现以下错误:

super(CCanvas,self).__init__(master=master,*args,**kwargs)
TypeError: must be type, not classobj

任何人都可以向我解释这种行为并告诉我如何解决它吗?

最佳答案

这里的问题是 TkInter 类(在 2.x 中)是旧式类。 Data Model 中详细描述了差异文档,但您不需要知道详细信息;你只需要知道you can't use super (以及如何通过显式调用 __init__ 来解决这个问题)。而且,正如 Steven Rumbalski 指出的那样,super() fails with error: TypeError “argument 1 must be type, not classobj”解释了当您尝试 super 的基类位于旧式类上时为什么会收到此错误消息。

这在文档中没有提到,除非你去寻找它,否则它并不是很明显,但如果你知道如何区分两者,就不那么难了。

正如 thread on python-list 中指出的那样,这通常不是问题,因为如果您需要新样式的类行为,您总是可以只执行 class CCanvas(tk.Canvas, object):

但是有几件事没有被处理,其中之一就是super 到基类的能力。相反,您必须以老式的方式做事并通过名称显式引用基类(这也意味着您必须显式传递 self):

def __init__(self,master,*args,**kwargs):
    TkInter.Canvas.__init__(self, master=master, *args, **kwargs)

(当然,另一种解决方案是已经迁移到 Python 3,那里没有旧式类……)

(为了完整起见,可以用旧式类伪造 90% 的 super,并且在早期的 2.x 时代有一些方法流传开来……但是你不想那样做。)

关于python - 继承自 Tkinter.Canvas - 调用 super 会导致错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14389918/

相关文章:

python - 使用 google-api-python-client 通过 Python 访问 Google Photo API

python - 新版python wheel发行后,gcloud应用部署超时

java - AWT 滚动 Pane 滚动条在调整大小时闪烁

javascript - 具有原型(prototype)的 parent 的多重继承

javascript - 所有圆圈都用相同的颜色绘制

javascript - getImageData 转换为 toDataURL HTML5

python - 使用 google appengine 在 django-nonrel 中保存实体

python - 如何判断服务器是否被锁定?

ios - 如何在初始化期间将值从子类传递到父类(super class)

python - 在 Python 中继承子方法