【问题标题】:How do I fix NoneType object is not callable error?如何修复 NoneType 对象不可调用错误?
【发布时间】:2019-10-04 05:26:57
【问题描述】:

我正在使用 Tkinter 每秒在画布中移动一个圆圈一定量,我在 Python 中遇到了 TypeError: 'NoneType' object is not callable 错误。我相信错误出在这段代码中:

def move(new_x0, new_y0, new_x1, new_y1):
    new_x0 = new_x0 + speed
    new_y0 = new_y0 + speed
    new_x1 = new_x1 + speed
    new_y1 = new_y1 + speed
    game.canvas.delete("all")
    obj = game.canvas.create_oval(new_x0, new_y0, new_x1, new_y1, fill = color)
    game.canvas.pack()
t = threading.Timer(1.0, move(x0, y0, x1, y1))
t.start()

我希望画布上的圆圈在 1 秒后移动一次位置,但它只显示 NoneType 错误。

编辑:对不起,我忘了显示错误。在这里。

Exception in thread Thread-1:
Traceback (most recent call last):
    File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\threading.py", line 917, in _bootstrap_inner
        self.run()
    File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\threading.py", line 1158, in run
        self.function(*self.args, **self.kwargs)
TypeError: 'NoneType' object is not callable

编辑:我通过执行 return obj 解决了 NoneType 错误,然后我得到 int object is not callable,我通过执行 ShadowRanger 的建议解决了这个问题,所以我的代码现在可以工作了。

【问题讨论】:

  • 哪个错误?不可迭代或不可调用?
  • 显示完整的回溯
  • 我不确定它是否需要参数,但我相信您打算将对move 的调用包装在lambda 中。您将 move 的返回值传递给计时器,它不会返回任何内容。我不确定您是否想要 x0 等定期更新。
  • 您的错误在这里:t = threading.Timer(1.0, move(x0, y0, x1, y1)) Timer 的第二个参数必须是函数。您正在传递None(函数move 没有return 语句,因此它隐式返回None)。所以当它尝试调用该函数时,它最终会尝试调​​用None,这当然会产生错误。
  • @TomKarzes 我不确定如何解决这个问题。你能帮我写出代码吗?

标签: python python-3.x tkinter tkinter-canvas nonetype


【解决方案1】:

threading.Timer 期望将函数作为其第二个参数传递。

解决此问题的一种简单方法是:

t = threading.Timer(1.0, lambda: move(x0, y0, x1, y1)) 

【讨论】:

    【解决方案2】:

    假设您的错误是可迭代错误,正如您在帖子顶部声明的那样。那么您的代码与您发布的代码不同。

    Timer() 将可迭代参数(元组、列表等)或关键字参数作为第三个参数。

    move(x0, y0, x1, y1)
    

    None,作为没有return语句的函数隐式返回None。正如错误所述,None 不可迭代。

    要修复您的代码,请传入一个可迭代对象。

    现在让我们假设您的代码与您发布的一样,错误是None 不可调用。在这种情况下,您必须传递一个函数对象(去掉括号),然后将move() 的参数作为可迭代对象放在后面(在这种情况下为Timer(1.0, move, [x0, y0, x1, y1]

    记住,Timer() 接受这些参数:

    Timer(time, function, iterable, kwargs)
    

    编辑:您澄清说您的错误不是可迭代的。参考第二个例子

    【讨论】:

    • 错误在于它不可调用,而不是不可迭代。查看堆栈跟踪。 Timer 的第二个参数必须是函数,而不是可迭代对象。
    • 您可能只想说在这种情况下必须如何调用Timerthreading.Timer(1.0, move, (x0, y0, x1, y1))
    猜你喜欢
    • 2017-02-07
    • 2022-11-16
    • 1970-01-01
    • 2018-12-03
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    相关资源
    最近更新 更多