为啥在初始化新进程时出现 NameError?
Posted
技术标签:
【中文标题】为啥在初始化新进程时出现 NameError?【英文标题】:Why am I getting a NameError when initializing a new Process?为什么在初始化新进程时出现 NameError? 【发布时间】:2021-02-15 21:34:09 【问题描述】:我正在使用应该是下载管理器的 tkinter 和 urllib 制作这个应用程序,并决定为每次下载使用 multiprocessing,但是,我遇到了问题.每次我点击“下载”按钮从我的小部件中获取信息以开始下载时,我都会收到 名称错误,说我的小部件未定义。 我尝试将小部件设为全局,甚至在我的函数中全局调用小部件,甚至将它们作为参数传递,但显然它们都不起作用。我认为这可能与我的程序结构有关,所以我在一个更简单的模拟程序上对其进行了测试,但仍然出现相同的错误。为什么会这样?模拟程序:
from tkinter import *
from multiprocessing import Process
times_clicked = 0
def change_lbl():
global times_clicked
times_clicked += 1
lbl.config(text=f"Clicked: times_clicked")
if __name__ == '__main__':
root = Tk()
root.geometry("300x300")
lbl = Label(root, text="Waiting for clicks...")
def start():
Process(target=change_lbl, daemon=True).start()
btn = Button(root, text="Add to clicks...", command=start)
lbl.pack(pady=10)
btn.pack()
root.mainloop()
错误:
Process Process-1:
Traceback (most recent call last):
File "C:\Users\Family\AppData\Local\Programs\Python\Python38-32\lib\multiprocessing\process.py", line 315, in _bootstrap
self.run()
File "C:\Users\Family\AppData\Local\Programs\Python\Python38-32\lib\multiprocessing\process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\Family\PycharmProjects\8-bit Downloader\pyfile.py", line 10, in change_lbl
lbl.config(text=f"Clicked: times_clicked")
NameError: name 'lbl' is not defined
【问题讨论】:
tkinter 小部件不能跨进程共享。改用线程。 谢谢@acw1668,但实际上我在多处理之前尝试了线程。我切换到多处理的原因是因为terminate()
函数。我尝试在线程中使用事件进行相互通信来告诉线程何时启动和停止,但显然它不适用于urllib.request.urlretrieve()
。如果您知道我可以停止 urlretrieve 线程的任何方法,请告诉我!
您可以将回调分配给urlretrieve()
的reporthook
选项。在回调中,您可以根据全局标志引发异常以中止下载。当然你最好在运行urlretrieve()
时使用try/except。
Here 是一个使用reporthook
回调来中止下载的简单示例。
【参考方案1】:
你必须定义lbl
写类似的东西
lbl = #something you need
【讨论】:
你好,@Oliver Hnat。感谢您的建议,但似乎它不起作用。我试过了,看起来我也必须重新定义整个根,所以我认为这不是最好的方法。以上是关于为啥在初始化新进程时出现 NameError?的主要内容,如果未能解决你的问题,请参考以下文章
导入类中的模块,但是在类方法中使用模块时出现NameError
运行规范命令时未初始化的常量 Spec::Rails (NameError)
为啥我在 Scriptella 中输出 CSV 文件时出现双引号?
为啥长臂猿会抛出“未初始化的常量 Gibbon::API (NameError)”