【问题标题】:Get an array out of a function without calling that function?从函数中获取数组而不调用该函数?
【发布时间】:2020-08-23 21:29:33
【问题描述】:

我是一名 Python 初学者,正在使用 tkinter 开发 gui。 我有一个按钮,它调用一个函数来打开一个 csv 文件并读取它, 然后我想从函数中获取这个文件中的值,以便在另一个函数中使用它。正如下面的示例代码所示,我使用return [XX , YY] 语句来获取数组,然后分配它们(XX, YY = Read_CSV())。虽然这可行,但问题是当我运行代码时,在我单击按钮之前,会弹出打开框对话框。那是因为在XX, YY = Read_CSV() 中,我正在调用一个应该仅在单击按钮时才调用的函数。

如何在不调用该函数的情况下分配这些数组并将它们从函数中取出?

from tkinter import *
import pandas as pd
from tkinter import filedialog

root = Tk()
root.geometry('200x200')
Frame=LabelFrame(root, text='Frame').pack()

def Read_CSV():
    CSV_File_Name = filedialog.askopenfilename(initialdir='/Desktop',
                                               title='Select Data File',
                                               filetypes=(('All files', '*.*'),
                                                          ('CSV file', '*.csv')))

    Data_CSV = pd.read_csv(CSV_File_Name, names=["A", "B"])

    XX = (Data_CSV['A']);
    YY = (Data_CSV['B'])

    return [XX, YY]


XX, YY = Read_CSV()
print(XX)

CSV_Read_Button = Button(Frame, text='Load Data', command=Read_CSV)
CSV_Read_Button.pack()

root.mainloop()

【问题讨论】:

  • 你不能。 XXYY 在函数中的其余代码运行之前不能有值。你为什么还要XX, YY = Read_CSV()呢?除了打印之外,您从不使用任何一个值。摆脱那条线。
  • 不要使用XX, YY = Read_CSV() - 你不需要它。问题是,当按钮运行代码时,它无法获取您使用return 发送的值,您必须在Read_CSV 中使用global 变量才能将其置于函数之外。
  • 顺便说一句:参见PEP 8 -- Style Guide for Python Code - 它建议lower_case_names 用于变量和函数,CamelCaseNames 仅用于类。它使代码更具可读性。
  • 您可以将一个列表传递给Read_CSV(),并使用该列表来存储返回值。
  • 谢谢大家,@furas 的回答解决了这个问题。这段代码实际上是重现我的问题的一个例子,我的代码中有这个问题,这里带来了更加复杂和混乱的问题。再次感谢。

标签: python arrays function tkinter dialog


【解决方案1】:

首先:不要使用XX, YY = Read_CSV(),因为它会立即运行代码——但你不需要它。

第二:问题是当您按下按钮并运行您的功能时,它并不关心您使用return 发送的内容,因为它不知道如何处理这些值(您无法通知按钮它必须将其分配给XX, YY),此时您需要global 将值直接分配给外部变量。

import tkinter as tk
from tkinter import filedialog
import pandas as pd

# --- functions ---

def read_csv():
    global xx  # use external variable instead of local one
    global yy  # use external variable instead of local one
    
    filename = filedialog.askopenfilename(initialdir='/Desktop',
                                          title='Select Data File',
                                          filetypes=(('All files', '*.*'),
                                                     ('CSV file', '*.csv')))


    if filename: # when user use `Cancel` then `filename will be `None`
        data = pd.read_csv(filename, names=["A", "B"])
        xx = data['A']  # it will assign to external variable
        yy = data['B']  # it will assign to external variable

    print(xx, yy)

# --- main ---

xx = None  # default value at start
yy = None  # default value at start

root = tk.Tk()

frame = tk.LabelFrame(root, text='Frame')
frame.pack() # you have to do in separated line because `frame = tk.LabelFrame().pack()` gives `None` in `frame`

csv_read_button = tk.Button(frame, text='Load Data', command=read_csv)
csv_read_button.pack()

root.mainloop()

如果您要添加使用xxyy 的函数并且意外地可以在加载数据之前运行,那么最好在开始时使用一些默认值创建xxyy(即@ 987654331@) 并检查函数如果 xx,yy 不是 None 在您尝试从 xx, yy 获取值之前


当你这样做时

frame = tk.LabelFrame(root, text='Frame').pack()

然后您将None 分配给frame,因为pack()/grid()/place() 返回None。您必须分两行将小部件分配给变量。

frame = tk.LabelFrame(root, text='Frame')
frame.pack()

filedialog 中,有人可以点击Cancel,然后filename 将变为None,因此您应该在尝试使用filename 读取数据之前检查它。


PEP 8 -- Style Guide for Python Code

【讨论】:

  • 这解决了我的问题。谢啦。我曾尝试使用全局变量,但似乎我在某个地方错了。 (您更正的代码的第一行有一个小错字,请编辑它。谢谢)
猜你喜欢
  • 2020-12-03
  • 2021-03-22
  • 1970-01-01
  • 2020-10-22
  • 2010-11-21
  • 1970-01-01
  • 2019-09-07
  • 1970-01-01
  • 2019-05-29
相关资源
最近更新 更多