【问题标题】:How to split up a Python application without relying on global variables? [duplicate]如何在不依赖全局变量的情况下拆分 Python 应用程序? [复制]
【发布时间】:2019-07-05 08:06:40
【问题描述】:

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

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

我尝试过全局变量,它们确实有效,但可能会导致不良习惯的形成,如果没有这些,我会收到有关变量超出范围和未定义的错误。

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

我希望能够在绑定到我的 GUI 的方法中使用变量,这样我就可以将应用程序拆分为多个文件,而不是将它们全部放在一个文件中,这似乎不切实际或不好的做法。我不确定使用类是否会更好,或者是否有更好的方法来实现我想要实现的目标。

【问题讨论】:

  • 您可以使用类,这是避免全局可变状态的一种方法。另一种是简单地将数据作为参数传递给函数并从函数返回数据。如果没有更多细节,我认为没有人可以提供更具体的建议
  • How to make a cross-module variable? 的可能重复项 - 我在写完我的答案后去寻找这个 - 如果这个问题作为一个骗子被关闭,我将删除我的答案或标记为 community wiki.

标签: python


【解决方案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.py 和b.py。 a 更改 foo 和 b 中的函数看到更改。

【讨论】:

  • 如果我在方法中更改这些变量之一的值,有什么方法可以访问更新后的变量以在其他地方使用?
  • 如果你创建一个minimal reproducible example 你可以测试它。
  • @MLBeginner 创建带有变量 foo 的 a.py。从 b.py 导入 a 并检查 a.foo。正如二战所说,从小处着手。
  • @MLBeginner 查看编辑
【解决方案2】:

您需要在此处查看 OOP 或 object oriented programming。

使用 OOP,您可以定义 self.whatever = something,并且可以按照您想要的方式访问该变量。

了解 OOP 的好地方是 here.

【讨论】:

  • 我在 C++ 和 Java 中做过 OOP,我曾认为在 Python 中还有其他方法可以做事,因为我在这里读到的很多线程都谈到在 Python 中避免 OOP,但我可能不得不重新考虑。
  • @MLBeginner 在 Python 中“避免”OOP 基本上是不可能的,python 是纯粹的面向对象语言:everything 是一个对象。您可能听说过,您不必总是为所有内容编写类定义。
【解决方案3】:

是的,创建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...

【讨论】:

  • 在这种情况下,如果我使用按钮允许用户选择目录中的文件位置,这不仅会更新 csv_open() 中的文件路径吗?然后我如何在 pre_processing_split() 中访问它而不需要用户再次选择路径?
  • 附加为self 的属性,如图所示。
  • 我第一次没有看到进一步的编辑或错过了它,谢谢。我会努力解决这个问题,我认为(希望)它会解决我的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-02
  • 2017-04-29
  • 2016-10-05
  • 2021-05-04
  • 2017-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多