英文:
How to use value from one python script to another
问题
我有两个Python脚本。
Script1.py 包括:
``` python
import tkinter as tk
def button_click():
exec(open("script2.py").read())
def main():
global entry_field
root = tk.Tk()
entry_field = tk.Entry(root)
entry_field.pack()
button = tk.Button(root, text="Click me!", command=button_click)
button.pack()
root.mainloop()
if __name__ == "__main__":
main()
第二个Python脚本是"Script2",包括:
import tkinter as tk
import script1
root = tk.Tk()
label = tk.Label(root, text=script1.entry_field.get())
label.pack()
root.mainloop()
我的想法是:我想要传递我在script1.py中键入的值,在之后我想要在script2.py中使用这个值并在标签上显示出来。
当我运行这段代码时,我遇到了一个错误:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "c:\Users\User\Desktop\Skaala\Skaala project\Test folder\script1.py", line 4, in button_click
exec(open("script2.py").read())
File "<string>", line 6, in <module>
AttributeError: module 'script1' has no attribute 'entry_field'
我会感激任何帮助。
编辑:
我稍微更改了代码,并移除了 "if name == "main":" 语句,现在它只实现了一半。当我运行 "Script1.py" 时,它会打开两次。这就是为什么我使用了 "if name == "main":",因为 "Script2.py" 从 "Script1.py" 导入数据,然后再次运行整个脚本。
<details>
<summary>英文:</summary>
I have 2 python scripts.
Script1.py includes:
``` python
import tkinter as tk
def button_click():
exec(open("script2.py").read())
def main():
global entry_field
root = tk.Tk()
entry_field = tk.Entry(root)
entry_field.pack()
button = tk.Button(root, text="Click me!", command=button_click)
button.pack()
root.mainloop()
if __name__ == "__main__":
main()
Second python script is "Script2" and includes:
import tkinter as tk
import script1
root = tk.Tk()
label = tk.Label(root, text=script1.entry_field.get())
label.pack()
root.mainloop()
My idea is: I want to pass value which I typed into entry field in script1.py, after I want to use this value and show it with label on script2.py.
When I run this code I'm getting an error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "c:\Users\User\Desktop\Skaala\Skaala project\Test folder\script1.py", line 4, in button_click
exec(open("script2.py").read())
File "<string>", line 6, in <module>
AttributeError: module 'script1' has no attribute 'entry_field'
I will appreciate for any help.
EDIT:
I've changed code a little bit, and removed "if name == "main":" statement, and now it works on half way. When I run "Script1.py" it opening twice. Thats why I used "if name == "main":", because "Script2.py" importing data from "Script1.py" and it runs full script again.
答案1
得分: 2
entry_field
,button
和root
只存在于Script1中main
函数的作用域内。如果你想在main
函数外部访问它们,你需要将它们的声明移到全局作用域之外。
编辑:
在Python中,类和函数定义了_作用域_。作用域确定了标签指代什么值。如果你在函数内部声明了某个东西,那个值只能在该函数的作用域内访问。也就是说,只能在函数体内部访问。在下面的例子中,我们有一个全局声明 g = 1
和一个函数 f1
,它赋值 g = 2
。请注意,这不是相同的 g
。它为一个全新的值创建了一个全新的标签。
g = 1
def f1():
# 创建一个本地变量 g,它与全局变量 g 不同
# 并且在函数之外是不可见的。
# 值为2,但全局的 g 仍然是1。
g = 2
def f2():
# 这次,变量 g 被声明为全局的,
# 因此 f2 内的任何对 g 的引用都将引用全局的 g。
global g
g = 2
def f3():
# 这次的代码将会崩溃,因为我们同时尝试
# 给本地变量 g 赋值和读取全局变量 g。
g += 1
f1()
print(g) # 打印 1
f2()
print(g) # 打印 2
f3() # 崩溃
exec
函数接受一个输入字符串并在当前作用域中运行它,因此你在答案中包含的代码实际上等同于这个:
import tkinter as tk
def button_click():
# 这一行:
# exec(open("script2.py").read())
# 等同于将代码粘贴到这里:
import tkinter as tk
import script1
root = tk.Tk()
label = tk.Label(root, text=script1.entry_field.get())
label.pack()
root.mainloop()
def main():
global entry_field
root = tk.Tk()
entry_field = tk.Entry(root)
entry_field.pack()
button = tk.Button(root, text="Click me!", command=button_click)
button.pack()
root.mainloop()
if __name__ == "__main__":
main()
这会造成问题,因为只有在调用main
之后,Script1才会有entry_field
属性。
我不太清楚为什么你要将这些代码分成两个不同的文件,并通过在它上面调用 exec
来“导入”Script2。你为什么这样做呢?有更好的将代码拆分成多个文件的方式,比如只需使用 import <filename>
。通常应该非常谨慎地使用exec
。
英文:
entry_field
, button
and root
only exist inside the scope of the function main
in Script1. If you want to access them outside the main
function, you need to move their declaration outside the function into the global scope.
Edit:
In Python, classes and functions define scope. Scope is what determines what labels refer to what values. If you declare something inside a function, that value will only be accessible inside that function's scope. I.e, anything inside the function body. In the example below, we have a global declaration g = 1
and a function f1
that assigns g = 2
. Note that this is NOT THE SAME g
. It's creating an entirely new label for an entirely new value.
g = 1
def f1():
# Creates a local variable g which is
# different from the global variable g
# and is not visible outside the function.
# The value is 2, but the global g is still 1.
g = 2
def f2():
# This time, the variable g is declared
# as global, so any references to g inside
# f2 will refer to the global g.
global g
g = 2
def f3():
# This time the code will actually crash with
# an UnboundLocalError, because the we're trying
# to assign the local variable g at the same time
# as we're trying to read the global variable g.
g += 1
f1()
print(g) #prints 1
f2()
print(g) #prints 2
f3() # crashes
The exec
function takes an input string and runs it in the current scope, so the code you included in your answer is actually equivalent to this:
import tkinter as tk
def button_click():
# This line:
# exec(open("script2.py").read())
# Is the same as just pasting the code here:
import tkinter as tk
import script1
root = tk.Tk()
label = tk.Label(root, text=script1.entry_field.get())
label.pack()
root.mainloop()
def main():
global entry_field
root = tk.Tk()
entry_field = tk.Entry(root)
entry_field.pack()
button = tk.Button(root, text="Click me!", command=button_click)
button.pack()
root.mainloop()
if __name__ == "__main__":
main()
This becomes a problem because Script1 will only have the attribute entry_field
after main
has been called.
It's not clear to me why you're putting this into two separate files and "importing" Script2 by calling exec
on it. Why are you doing that? There are better ways of splitting up code between files, such as just doing import <filename>
. exec
should generally be used very sparingly.
答案2
得分: 1
我想传递我在script1.py
中输入到输入字段的值,然后我想使用这个值并在script2.py
中的标签上显示它。
不建议使用exec(open("script2.py").read())
。这只是用于读取,而不是导入模块。
你不能从script2.py
切换到script1.py
,反之亦然,否则你的程序将冻结并且无响应。这可能需要大约15分钟或更长时间。
在script1.py
模块中:
使用root = tk.Tk()
和root.mainloop()
来完全编写脚本,而不是重复。
我们可以在函数之前的顶部放置root = tk.Tk()
。在这种情况下,我们可以使用root
传递给任何模块。
- 在
button_click()
函数中,只需使用import script2
调用script2
模块。 - 并调用
Script2.run()
函数。 - 在
button_click()
函数中删除root.mainloop()
。
在script2.py
模块中:
- 你需要使用
Toplevel
来调用第二个窗口。否则,你将看不到打印输出。 - 创建
run()
函数,并添加两个参数。这样我们可以从button_click()
函数中调用script1
模块。并声明变量core
,以便将root
传递给core
。
script1.py
片段:
import tkinter as tk
root = tk.Tk()
def button_click():
import script2
g = entry_field.get()
script2.run(root, g)
def main():
global entry_field
root.title('Main Window')
entry_field = tk.Entry(root)
entry_field.pack()
button = tk.Button(
root,
text="Click me!",
command=button_click
)
button.pack()
root.mainloop()
if __name__ == "__main__":
main()
script2.py
:
import tkinter as tk
def run(core, data):
core = tk.Toplevel()
core.title("Toplevel")
label_2 = tk.Label(core, text=data)
label_2.pack()
屏幕截图:
英文:
> My idea is: I want to pass value which I typed into entry field in
> script1.py, after I want to use this value and show it with label on
> script2.py.
It is not recommended to use exec(open("script2.py").read())
. It is merely to read, not import module.
You cannot swap from script2.py
to script1.py
and vice-versa, otherwise, you will freeze and not respond. It will take about 15 or more minutes.
On script1.py
module:
Use root = tk.Tk()
and root.mainloop()
entirely script instead of duplicating.
We can put root = tk.Tk()
at the top before the function. In that case, we can use root
to pass to any modules.
- On the
button_click()
function, just calledscript2
module using
import script2
. - And called
Script2.run()
function. - Remove
root.mainloop()
on the button_click() function.
On script2.py
module:
- You need to called second window using
Toplevel
. Otherwise, you
will not see print output. - Create
run()
function, and add two parameters. In that we can call from
button_click()
script1
module. And declare variablecore
. So we can passroot
tocore
.
Snippet script1.py
:
import tkinter as tk
root = tk.Tk()
def button_click():
import Script2
g = entry_field.get()
Script2.run(root, g)
def main():
global entry_field
root.title('Main Window')
entry_field = tk.Entry(root)
entry_field.pack()
button = tk.Button(
root,
text="Click me!",
command=button_click
)
button.pack()
root.mainloop()
if __name__ == "__main__":
main()
script2.py:
import tkinter as tk
def run(core, data):
core = tk.Toplevel()
core.title("Toplevel")
label_2 = tk.Label(core, text=data)
label_2.pack()
Screenshot:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论