提问人:phaynes 提问时间:5/18/2023 最后编辑:phaynes 更新时间:11/15/2023 访问量:24
在函数调用中使用返回值的最佳实践
Best practice for using Returned Value on Function Call
问:
为我的实用程序制作了一个基本的 Python,这是我学习如何编码的第一个项目,我知道这很混乱,这就是我在这里的原因。
在这个程序中,“上传XML文件”下面的按钮调用函数“browseXMLFiles”,下面的按钮调用“browseLOGFiles”函数(这两个函数的内容是相同的,除了它们查找的文件类型),然后“删除重复项”按钮调用“remove_invoices”函数。
很明显,前两个函数会打开一个 tkinter 文件对话框,您可以在其中分别找到 XML 和 LOG 文件。
找到文件后,路径存储在全局变量中,因此可用于在“remove_invoices”函数中执行工作。
例如,这是两个“browseX”函数全部包含的内容,而全局变量是我试图摆脱的内容:
def browseLOGFiles():
logname = filedialog.askopenfilename(initialdir = "/Logs",
title = "Select a File",
filetypes = (("Text files",
"*.txt*"),
("all files",
"*.*")))
global new_log_name
new_log_name = logname.split('/', -1)
logButton.configure(text=new_log_name[-1])
我目前的问题:
我正在尝试清理全局变量污染,所以我希望我的remove_invoices函数接受“browseX”函数的返回。我尝试将全局变量替换为函数本身(因为它现在返回路径:
def browseLOGFiles():
logname = filedialog.askopenfilename(initialdir = "/Logs",
title = "Select a File",
filetypes = (("Text files",
"*.txt*"),
("all files",
"*.*")))
new_log_name = logname.split('/', -1)
logButton.configure(text=new_log_name[-1])
return new_log_name
而不是使用全局变量)。最终发生的事情是,当单击“删除重复项”按钮时,它不会使用函数的返回项,而是在remove_invoices函数中再次调用该函数,从而使您再次选择文件路径。
我应该如何重构我的代码,以便我可以:
- 防止全球变量污染
- 获取前两个函数的结果,而无需在remove_invoices函数中再次调用它们:
功能:
def remove_invoices():
try:
error_file = open(browseLOGFiles(), "r") #This is closed later, I promise
except Exception as e:
if e == "name 'logname' is not defined":
statusLabel.configure(text="Please upload a LOG(.txt) file.")
try:
global tree
tree = ET.parse(browseXMLFiles)
print(f'Opened {browseXMLFiles}. Parsing.')
except:
print(f"Can't find file the specified XML File. Was the filename typed exactly, including the extension?")
答:
我早就想通了,但我还是把它放下吧。
我的解决方案基本上是将与打开文件相关的任何内容移动到其自己的名为 FileHandler 的类中。我手头没有确切的代码,但我会在这里复制它:
class FileHandler:
def __init__(self):
self.log_name = None
self.tree = None
def browseLOGFiles() -> None:
logname = filedialog.askopenfilename(initialdir = "/Logs",title = "Select a File",filetypes = (("Text files","*.txt*"),("all files","*.*")))
new_log_name = logname.split('/', -1)
logButton.configure(text=new_log_name[-1])
self.log_name = new_log_name
我没有返回值,而是将 self.value 分配给日志名称。现在,如果我需要访问当前日志名称,我可以实例化我的类并调用该值:
fh = FileHandler()
fh.browseLOGFiles() # No longer returns value, instead assigns to class var
print(fh.log_name)
这解决了我的全局命名空间污染问题,并允许我在需要它们的地方访问这些变量。
这是在我对类做很多实验之前,但如果你是 Python 或整个编码的新手,我保证它们比看起来更容易理解。它们一开始非常令人生畏,但会让你的生活更轻松。
评论