gpt4 book ai didi

python - tkinter 消息框的子导入问题

转载 作者:太空宇宙 更新时间:2023-11-03 16:53:47 25 4
gpt4 key购买 nike

我正在使用 tkinter 编写一个 GUI 应用程序,现在我想使用 tkinter 内置的消息框,所以我想既然我已经导入了 tkinter(作为 tk),那么它就是 tk.messagebox.showerror()但这或多或少有效......

我通过 IDLE 运行它时没有任何问题,但如果我使用 python <module-name>.py在终端中它会抛出一个 AttributeError。

这是我可以制作的最简单的示例:

import tkinter as tk

root = tk.Tk()
tk.messagebox.showerror(title="Test Error", message="This is a test")
root.mainloop()

现在,如果我添加from tkinter import messagebox,事情就会变得更加奇怪。作为导入,从终端运行时,相同的代码可以工作(保留 tk.messagebox.showerror )。显然它仍然必须被视为 tkinter 的一个属性,那么为什么它在没有显式导入的情况下不起作用呢?

我想我并不是真的在寻找这样的解决方案(因为我找到了一些让它发挥作用的方法),而是更多地解释了为什么会发生这种情况。

一如既往,欢迎提出任何建议!

最佳答案

这个问题以前曾以“为什么import tkinter; tkinter.font在IDLE中工作但在Python本身中不起作用?”的形式出现过。解释是 import 的工作方式和 IDLE 当前如何设置执行代码的子进程之间的交互。

IMPORT:sys.modules 是一个字典,它将模块名称映射到导入的模块对象。在较高级别上,import modname 相当于以下内容。

if modname not in sys.modules:
sys.modules[modname] = module(modname)
modname = sys.modules[modname]

对于 python 编码的包,模块是从 modname/__init__.py 创建的。导入包不会导入其子模块。也就是说,它不运行 modname/submodule.py。随后导入子模块会将子模块作为属性添加到 sys.modules 和包中。之后导入模块会将现有模块(该模块具有子模块作为属性)绑定(bind)到指定的名称。

IDLE:当前,当 IDLE 设置子进程来运行代码时,它会直接或间接导入 tkinter 及其子模块。 (代码位于idlelib/run.py及其导入的idlelib模块中。)这可以通过运行看到

for name in sys.modules:
if name.startswith('tkinter'):
print(name)

当 IDLE 启动时。因此,当您运行 import tkinter 时,这是该过程中的第二次 tkinter 导入,并且名称 'tkinter' 绑定(bind)到具有子模块作为属性的现有 tkinter 模块

解决方案:IDLE 的目的是开发在 python 本身中运行的代码。 IDLE 运行无法在 python 中运行的有缺陷代码是一个错误。我正在研究refactoring idlelib这样上面就不会打印任何东西。唯一需要的 tkinter 模块是 tkinter.messagebox,并且仅当存在阻止运行代码的问题时才需要该模块。因此,messagebox 的导入可以延迟到需要时才导入,但这种情况很少见。

关于python - tkinter 消息框的子导入问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35619027/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com