如何执行依赖于在另一个pythongui脚本中提取文件名的python脚本?

p3rjfoxz  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(340)

我创建了一个python脚本( NoShowCalc.py )它使用3个选定的excel文件自动进行数据清理和分析( booked_file_path , arrived_file_path ,和 vlookup_file_path ). 但是,我希望这一切都是通过gui执行的,所以我开始了一个单独的( GUI.py )脚本来创建一个带有浏览按钮的界面,该按钮将获取这些文件路径名,然后将获取执行 NoShowCalc.py 脚本。一旦选择了这些excel文件,就会有另一个按钮来执行 NoShowCalc.py 脚本。然而,我做到了,而且成功了!但我不知道我改变了什么,现在两个不同的py文件没有连接。
这是书里的剧本 NoShowGUI.py 脚本:

def open_file():
browse_text.set('Loading...')
booked_file_path = askopenfile(parent=root, mode='rb', title='Choose a file', filetype=[('CSV file', '*.csv')])
if booked_file_path:
    read_csv = (booked_file_path)
    browse_text.set('Loaded')
def run():
    os.system('NoShow_Calc.py')
    calculate_text.set("Calculating...")

# Calculate button

calculate_text = tk.StringVar()
calculate_btn = tk.Button(root, textvariable=calculate_text, command=lambda:run(), font='Calibri', fg='black', height=1, width=15)
calculate_text.set("Calculate No Show")
calculate_btn.grid(column=2, row=9)

这是第一行 NoShowCalc.py 脚本:

import pandas as pd 

booked = pd.read_csv(booked_file_path, parse_dates=['Appointment Date'])
arrived = pd.read_csv(arrived_file_path, parse_dates=['Appointment Date'])
vlookup = pd.read_excel(vlookup_file_path)

不断出现的错误是 NameError: name 'booked_file_path' is not defined . 我不知道它以前是如何运行的,现在这个错误突然出现,因为它不能再与另一个py文件通信了。我做错了什么?

wztqucjr

wztqucjr1#

如果使用 os.system() 或使用模块 subprocess 那么就不能使用其他脚本中的变量。它们作为独立的进程运行,不能共享变量(或内存中的数据)
只能将一些文本值作为参数发送

os.system('NoShow_Calc.py ' + booked_file_path)

然后你就可以进去了 NoShow_Calc 使用 sys.argv ```
import pandas as pd
import sys

booked_file_path = sys.argv[1]

booked = pd.read_csv(booked_file_path, parse_dates=['Appointment Date'])
arrived = pd.read_csv(arrived_file_path, parse_dates=['Appointment Date'])
vlookup = pd.read_excel(vlookup_file_path)

如果需要其他变量,则必须以相同的方式发送其他值

os.system('NoShow_Calc.py ' + booked_file_path + ' ' + other_filename)

booked_file_path = sys.argv[1]
other_filename = sys.argv[2]

etc.

但是使用 `os.system()` 无法发送结果 `booked, arrived, vlookup` 从 `NoShow_Calc` 至 `NoShowGUI` .
你可以和我一起做 `subprocess` 但它只能以文本形式发送-所以 `NoShow_Calc` 必须使用 `print()` 显示所有结果和 `NoShowGUI` 必须将此文本解析为预期的结构-即列表、字典, `DataFrame` 你最好用 `import` 从中加载代码 `NoShow_Calc.py` 然后所有的代码都在同一个进程中运行,这样所有的代码都可以访问相同的变量,并且不需要转换成文本和从文本返回。
为了使它更好,我把代码放在函数中

import pandas as pd

def my_function(booked_file_path, arrived_file_path, vlookup_file_path):
booked = pd.read_csv(booked_file_path, parse_dates=['Appointment Date'])
arrived = pd.read_csv(arrived_file_path, parse_dates=['Appointment Date'])
vlookup = pd.read_excel(vlookup_file_path)

return booked, arrived, vlookup
然后在 `NoShowGUI` 您可以导入它并像任何其他函数一样使用它

from NoShow_Calc import my_function

booked, arrived, vlookup = my_function(booked_file_path, arrived_file_path, vlookup_file_path)

编辑:
我做了最小的工作代码。我把它简化为一个文件名。
无显示计算

import pandas as pd

def calc(booked_file_path): #, arrived_file_path, vlookup_file_path):
booked = pd.read_csv(booked_file_path, parse_dates=['Appointment Date'])
#arrived = pd.read_csv(arrived_file_path, parse_dates=['Appointment Date'])
#vlookup = pd.read_excel(vlookup_file_path)

return booked #, arrived, vlookup
noshowgui.py文件

import tkinter as tk
from tkinter.filedialog import askopenfilename # instead of askopenfile

adding directory with this script to sys.path before import NoShow_Calc

to make sure that import will search NoShow_Calc.py in correct folder even when GUI will be run from different folder

import os
import sys

HOME_DIR = os.path.dirname(os.path.abspath(file))
sys.path.append(HOME_DIR)

import NoShow_Calc

print('HOME_DIR:', HOME_DIR)

def select_filename():
global booked_file_path # inform function that it has to assign value to external/global variable

text_log.insert('end', 'Selecting ...\n')

# use `askopenfilename` instead of `askopenfile` 
# because I need only filename, not opened file (pandas will open it on its own)

booked_file_path = askopenfilename(parent=root,                                        
                                   title='Choose a file', 
                                   #initialdir='/home/furas',
                                   filetypes=[('CSV file', '*.csv')])

if booked_file_path:
    text_log.insert('end', f'Selected: {booked_file_path}\n')
else:
    text_log.insert('end', f'Not selected\n')

def run():
text_log.insert('end', "Calculating...\n")

if booked_file_path is None:
    text_log.insert('end', "File booked_file_path not selected !!!")
    return
#elif arrived_file_path is None:
#    text_log.insert('end', "File arrived_file_path not selected !!!")
#    return
#elif vlookup_file_path is None:
#    text_log.insert('end', "File vlookup_file_path not selected !!!")
#    return
else:        
    root.update()  # force tkinter to update text in text_log at once (not when it exits function `run`)
    result = NoShow_Calc.calc(booked_file_path)# , arrived_file_path, vlookup_file_path)

text_log.insert('end', "Result:\n")
text_log.insert('end', str(result.head()) + "\n")

--- main ---

booked_file_path = None # default value at start (so in run I can check None to see if I selecte filename)

arrived_file_path = None

vlookup_file_path = None

root = tk.Tk()

text_log = tk.Text(root)
text_log.grid(column=0, row=0)

select_btn = tk.Button(root, text="Select File Name", command=select_filename)
select_btn.grid(column=0, row=1)

calculate_btn = tk.Button(root, text="Calculate", command=run)
calculate_btn.grid(column=0, row=2)

root.mainloop()

![](https://i.stack.imgur.com/h3ANq.png)

相关问题