【问题标题】:Store pandastable dataframe into variable将 pandastable 数据帧存储到变量中
【发布时间】:2020-08-24 06:12:13
【问题描述】:

我目前有以下脚本,它读取导入的 csv 文件并在 tkinter GUI 中显示为 pandastable。

在导入文件时,它会添加 x2 个额外的列 self.table.addColumn("Current Status") 和 self.table.addColumn("Assign Technician")。

如何将更新后的pandastable dataframe 存储到class TestApp(tk.Frame): 之外的变量中,以便稍后在我的代码中调用dataframe 上的其他函数?

我之前使用过global 变量,以便稍后可以调用从外部函数中创建的variable,但不确定这是否是我为此目的所需要的。

import csv
import tkinter as tk
import tkinter.ttk as tkrttk
from tkinter import *
from tkinter import filedialog

import pandas as pd
from pandastable import Table, TableModel



root = tk.Tk()
root.geometry("2000x1000")
root.title('Workshop Manager')


def select_input_file():
    global input_file_path
    input_file_path = filedialog.askopenfilename(
    filetypes=(("CSV files", "*.csv"),))
    app = TestApp(root, input_file_path)
    app.place(bordermode = INSIDE,height = 500, width = 2000, x =0, y=50)
    

class TestApp(tk.Frame):
     def __init__(self, parent, input_file_path, editable = True, enable_menus = True):
        super().__init__(parent)
        self.table = Table(self, showtoolbar=False, showstatusbar=False)
        self.table.importCSV(input_file_path)
        self.table.show(input_file_path)
        self.table.addColumn('Current Status')
        self.table.addColumn('Assign Technician')
        self.table.autoResizeColumns()

root.mainloop()

【问题讨论】:

    标签: python pandas tkinter


    【解决方案1】:

    这里不一定需要global 变量。您可以通过使用对象本身直接访问类的成员属性。所以在这种情况下,您可以使用app.table 访问TestApp 类的table attr,看起来像这样,

    def select_input_file():
        #...
        app = TestApp(root, input_file_path)
        app.place(bordermode = INSIDE,height = 500, width = 2000, x =0, y=50)
    
        df = app.table     # contains the updated table which can be passed to other functions
        newFunc( df )      # sample call
    
    

    【讨论】:

    • 如果我使用df = app.table 然后print(df) 我得到输出.!testapp.!table 这是对象名称?
    • 是的,就是表格对象,如果你想打印里面的数据框,你可以从df = app.table.model.df得到它然后做print(df)
    【解决方案2】:

    避免使用global 来实现这一点。

    目前,您的所有有状态变量都存在于模块(文件)中。您可以在TestApp 之外对您的表执行相同的操作,然后通过__init__ 传递它:

    import csv
    import tkinter as tk
    import tkinter.ttk as tkrttk
    from tkinter import *
    from tkinter import filedialog
    
    import pandas as pd
    from pandastable import Table, TableModel
    
    
    table = Table(showtoolbar=False, showstatusbar=False)
    
    root = tk.Tk()
    root.geometry("2000x1000")
    root.title('Workshop Manager')
    
    
    def select_input_file():
        global input_file_path
        input_file_path = filedialog.askopenfilename(
        filetypes=(("CSV files", "*.csv"),))
        app = TestApp(root, input_file_path)
        app.place(bordermode = INSIDE,height = 500, width = 2000, x =0, y=50)
        
    
    class TestApp(tk.Frame):
         def __init__(self, parent, input_file_path, editable = True, enable_menus = True, table=table):
            super().__init__(parent)
            self.table = table
            self.table.importCSV(input_file_path)
            self.table.show(input_file_path)
            self.table.addColumn('Current Status')
            self.table.addColumn('Assign Technician')
            self.table.autoResizeColumns()
    
    root.mainloop()
    

    任何可以看到模块命名空间的东西现在都可以访问您的表对象。这里table是一个可变对象,所有的变化都会反映到任何访问该对象的函数上。

    一个建议:最好将定义(类、函数)与运行时创建的有状态位分开。这将极大地帮助澄清依赖关系。通常使用文件底部的if __name__ == "__main__": 行来启动应用程序的“脚本”部分,保留上面的所有定义。我见过一些包(看着你,Flask!)有点打破这个惯例,这可能会让人头疼。

    就此而言,您的 select_input_file 函数存在一些问题。没有充分的理由在那里创建应用程序实例。例如,更好的选择是将其作为 App 类中的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-13
      • 1970-01-01
      • 1970-01-01
      • 2021-02-18
      • 1970-01-01
      • 1970-01-01
      • 2018-04-15
      • 1970-01-01
      相关资源
      最近更新 更多