我试图执行此代码:
import Tkinter as tk
import tkFont
import functools
import math
import random
import time
class Pong(tk.Canvas):
DEFAULTS = dict(width=640, height=480,background='black',highlightthickness=0)
def main(cls):
root = tk.Tk()
root.title('Pong')
root.resizable(False, False)
root.bind_all('<Escape>', lambda event: root.destroy())
game = cls(tkFont.Font(family='Book Antiqua', size=15, weight='bold'), 5, 100,background='black', width=640, height=480)
game.grid()
root.mainloop()
但我有这些错误:
Traceback (most recent call last):
line 413, in <module>
pong.main()
, line 17, in main
game = cls(tkFont.Font(family='Book Antiqua', size=15, weight='bold'), 5, 100,background='black', width=640, height=480)
AttributeError: Pong instance has no __call__ method
答案 0 :(得分:1)
到目前为止我可以看到一个主要问题
cls作为变量进入
def main(cls):
然后你就像一个函数
一样使用它game = cls(tkFont.Font(family='Book Antiqua', size=15, weight='bold'), 5, 100,background='black', width=640, height=480)
答案 1 :(得分:0)
正如您在评论中提到的,这是您创建pong
并致电main
的方式:
if __name__ == '__main__':
pong = Pong()
pong.main()
当您致电Pong()
时,您正在创建实例。因此,您调用的main
方法是实例方法,其中第一个隐式参数是实例本身。通常,此参数的名称为self
,例如方法,而不是cls
。
因此,如果我们重命名它,那么事后发生的事情就很明显了:
game = self(tkFont.Font(…), 5, 100, background='black', width=640, height=480)
请注意,self
是Pong
的对象和实例。所以它不是一个函数,也不是你可以调用的构造函数;你实际上是在尝试调用那里不起作用的实例。
我认为您实际想要做的是将main
作为“静态”方法,作为应用程序的入口点。在这种情况下,您应该在方法声明前面添加@classmethod
装饰器:
@classmethod
def main(cls):
root = tk.Tk()
# …
在这种情况下,cls
确实是Pong
类型,您可以稍后调用它来创建Pong
对象。
您应该将__name__ == '__main__
部分更改为仅Pong.main()
,因为您不再为{em>实例调用main
,而是整个类型。
if __name__ == '__main__':
Pong.main()
答案 2 :(得分:0)
您正在做一件非常奇怪的事情 - 您正在创建tk.Canvas的子类,但在创建此对象之前,您不会初始化tk。这不是使用tkinter的正确方法。您应该在此类范围之外初始化Tk,或者不从tk.Canvas继承。
我建议您重新构建代码,以便首先初始化tkinter,然后然后创建游戏实例。
例如:
import Tkinter as tk
class Pong(tk.Canvas):
def __init__(self, root):
tk.Canvas.__init__(self, root)
<put other "main" code here if you want>
if __name__ == "__main__":
root = tk.Tk()
pong = Pong(root)
pong.pack(fill="both", expand=True)
root.mainloop()