构建多模块python程序的最pythonic方法是什么?

时间:2013-06-02 18:26:55

标签: python oop module

我在一个文件中构建了一个相当大的程序。文件的大小使它变得不可行,所以我决定分成多个模块,但后来有一个变量范围的主要问题。我已经在很大程度上解决了这个问题(在此过程中学习了很多东西),但我很想理解良好的结构,以避免未来的经验教训。有几个具体要点,但也欢迎一般建议。

需要共享相同名称空间的模块

我有两个模块似乎需要共享相同的命名空间。一个是程序的主流(它向对象传输数据和从对象传输数据,并调用UI),另一个是UI(响应用户输入,调用主流)。

是否每个模块都导入另一个模块,然后主文件导入两者?这对我来说并不是特别优雅。

来自[modulename] import *

在这个问题的答案中:

Python: Sharing global variables between modules and classes therein

有人建议应避免使用from [modulename] import *

使用from [modulename] import *构建一组只有类定义的模块是否可以?什么是"安全"用例?

1 个答案:

答案 0 :(得分:1)

需要访问彼此命名空间的模块与需要共享相同命名空间的模块不同。我无法想到您使用from modulename import *无法做的任何事情。import modulename。你只需要在modulename.前面写下很多你的名字。这是好事,不是坏事。它使您的代码自我记录,这就是为什么要避免使用from modulename import *

您可以让UI和主流模块相互导入。遇到问题的唯一方法是在函数范围之外引用它们之间的名称。例如

# mainflow.py
import ui # interpreter stops reading mainflow and starts reading ui

class Foo:
    ...

theUI = ui.UI()

# ui.py
import mainflow # mainflow already being loaded; interpretation of ui continues uninterrupted

def dosomething():
    myfoo = mainflow.Foo() # so far so good, not interpreted until the function is called

class Bar(mainflow.Foo): # mainflow.Foo not reached yet, error here
    ...

class UI:
    ...

另一方面,如果ui碰巧先被导入,那么当{@ 1}}出现所有mainflow时,你都会得到错误,但ui只被解释为theUI = ui.UI()。但是,只要你把所有引用都放在函数中,你就可以相处得很好。 E.g。

import mainflow

类之间的依赖性仍然存在问题;我建议你不要做那样的事情。但如果你这样做了,你可以用这种奇怪的方法使整个事情发挥作用:

# mainflow.py
import ui
...

theUI = None

def initialize():
    global theUI
    theUI = ui.UI()

现在使用ui.py的第一个版本和mainflow.py的最后一个版本,程序将编译并运行。我不是真的推荐以上;更好地组织您的代码,以便您没有这种依赖。但是,如果您拥有的只是在模块中的函数之间来回调用,则不必采用这些技巧。

有更多面向对象的设计方法使您的UI和您的程序流不直接相互依赖,但这样的重新设计将比仅使用# mainflow.py ... theUI = None def initialize(): global theUI theUI = ui.UI() import ui # Waht!? Crazy! Import at the bottom of a file. Now all of mainflow's names are guaranteed to exist and ui can access them. 复制和粘贴到文件和名称前缀更复杂除非你有特殊的原因,否则我认为你不想过度重新设计。