Python 为什么文件写入后为空?
我有一个tkinter应用程序和一个将一些数据写入文件的线程。如果我让线程完成它的工作,文件是空的。如果我在线程完成之前终止程序(单击pyCharm中的红色方块),则文件将充满数据,直到终止点。下面是重现问题的代码:Python 为什么文件写入后为空?,python,multithreading,file,tkinter,Python,Multithreading,File,Tkinter,我有一个tkinter应用程序和一个将一些数据写入文件的线程。如果我让线程完成它的工作,文件是空的。如果我在线程完成之前终止程序(单击pyCharm中的红色方块),则文件将充满数据,直到终止点。下面是重现问题的代码: import tkinter as tk import _thread import numpy as np img_list = [] def create_img_list(): for i in range(1000): img = np.ran
import tkinter as tk
import _thread
import numpy as np
img_list = []
def create_img_list():
for i in range(1000):
img = np.random.rand(385, 480)
img = img * 65535
img = np.uint16(img)
img_list.append(img)
def write_to_file():
f = open("test.Raw", "wb")
for img in img_list:
f.write(img)
f.close()
root = tk.Tk()
button = tk.Button(root, text="Click Me", command=_thread.start_new_thread(write_to_file, ())).pack()
create_img_list()
root.mainloop()
这里发生了什么以及如何修复它?当我将打印(img\u列表)
添加到写入文件()
时,我看到这个函数在开始时执行,没有点击按钮,甚至在创建img\u列表()
运行(创建列表)之前执行,所以写入文件()
写入空列表
您错误地使用了命令=
。它需要不带()
(所谓的“回调”)的函数名,但您运行函数并将其结果分配给命令=
。您的代码的工作方式如下
result = _thread.start_new_thread(write_to_file, ()) # it executes function at start
button = tk.Button(root, text="Click Me", command=result).pack()
但是你需要
def run_thread_later():
_thread.start_new_thread(write_to_file, ())
button = tk.Button(root, text="Click Me", command=run_thread_later).pack()
最终,您可以使用lambda
在command=
button = tk.Button(root, text="Click Me", command=lambda:_thread.start_new_thread(write_to_file, ())).pack()
顺便说一句:你有常见的错误
button = Button(...).pack()
它将None
赋值给变量,因为pack()
/grid()
/place()
返回`None'
如果以后需要访问按钮
,则必须分两行执行
button = Button(...)
button.pack()
如果以后不需要访问按钮
,则可以跳过`button()
@martineau哪两个线程?不要直接使用
\u thread
模块。除非您确切知道自己在做什么,否则您永远不想直接访问下划线\u modues
。改为使用threading
:command=threading.Thread(无,写入文件,())。开始。
@Dan首先初始化列表,然后单击按钮开始写入否,您没有<首先调用代码>写入文件。您可以通过向每个函数添加print(name)
来检查它。@Dan,您在线程方面做了哪些尝试?我在评论中表现了什么?因为这对我有用。添加print(img\u list)
到write\u-to\u-file()
,您将看到此函数在开始时执行,而无需单击按钮,甚至在运行创建列表的create\u-img\u-list()
之前执行,因此write\u-to-file()
写入空列表。您可以在命令=
中创建并启动AD,并将结果从线程分配给命令=
,但您应该分配普通函数,该函数稍后将创建线程并启动它。或者使用lambda
执行此命令-命令=lambda:\u线程。启动新线程(写入文件,())
Button(...).pack()