如何在不依赖全局变量的情况下拆分Python应用程序?

时间:2019-02-11 18:48:42

标签: python python-3.x tkinter

我一直在使用Tkinter创建一个基本的Python机器学习GUI。我没有创建非常长的内容或跨越多个.py文件或使用GUI的经验。

我发现自己使用很多全局变量来访问用户输入(例如文件路径),但是我知道这是一种不好的做法,并且最终可能会导致意大利面条式代码。

如何在没有全局变量的情况下更好地组织该应用程序,以便可以通过按下按钮等来利用在GUI中设置的变量?

我尝试了可以​​起作用的全局变量,但可能会导致不良习惯的形成,而没有这些,我会得到关于变量超出范围和未定义的错误。

到目前为止,当所有内容都在一个.py文件中时,该应用程序都可以运行,但是现在它正在增长,我想将其拆分为一个我正在努力的适当结构。

我的应用程序中的一个示例是让用户选择要使用的csv文件。所以我有:

def csvOpen():
    csvFilePath = filedialog.askopenfilename()

然后通过按钮调用哪个。但是我然后想在其他地方使用此csvFilePath,例如:

def csvDisplay():

    window2 = Toplevel() 
    csvFrame = Frame(window2)
    csvFrame.pack(fill=BOTH, expand=1)
    df = pd.read_csv(csvFilePath)
    window2.table = csvView = Table(csvFrame, dataframe=df, showtoolbar=False, showstatusbar=False)
    csvView.show()

和:

def pre_processing_split():
    np.random.seed(11)
    df = pd.read_csv(csvfile)

我希望能够在与GUI绑定的方法中使用变量,这样我就可以将应用程序拆分为多个文件,而不是将所有内容都放在一个文件中,这似乎不切实际或不可行。我不确定使用类代替会更好还是我尝试实现的目标是否有更好的方法。

3 个答案:

答案 0 :(得分:1)

如果您具有事先知道的名称/变量,请将其全部放入一个模块中,然后将该模块的内容导入所有其他模块中。也许该模块中的变量之一可以是包含一些内容的字典,或者可以在程序执行时添加到其中。


tmp.py:

foo = 'bar'

b.py:

import tmp

def f():
    return tmp.foo

a.py:

import tmp, b

print(b.f())
tmp.foo = 'ICHANGED!!'
print(b.f())

>>>
bar
ICHANGED!!

这有效。名称/变量foo是在tmp.py中定义/分配的;然后将其导入a.pyb.py中。 a更改了foo,而b中的功能看到了更改。

答案 1 :(得分:1)

您在这里需要做的是查看OOP或object oriented programming

使用OOP,您可以定义self.whatever = something,该变量将以您希望的方式进行访问。

研究OOP的好地方是here.

答案 2 :(得分:1)

是的,创建一个class似乎是最好的。

class CSVProccessor(object):
    def __init__(self, csv_file_path=None):
        self.csv_file_path = csv_file_path
        self.df = None

    def csv_open(self):
        self.csv_file_path = filedialog.askopenfilename()

    def csv_display(self):
        window2 = Toplevel() 
        csv_frame = Frame(window2)
        csv_frame.pack(fill=BOTH, expand=1)
        self.df = pd.read_csv(self.csv_file_path)
        window2.table = csv_view = Table(csv_frame,
                                         dataframe=df,
                                         showtoolbar=False,
                                         showstatusbar=False)
        csv_view.show()

    def pre_processing_split(self):
        np.random.seed(11)
        self.df = pd.read_csv(self.csv_file_path)

csv_processor = CSVProcessor()
csv_processor.csv_open()
# ...etc...