[英]What is the most pythonic way to structure a multi-module python program?
I've built a fairly sizeable program in a single file. 我已经在单个文件中构建了一个相当大的程序。 The size of the file was making it unworkable, so I decided to split into multiple modules, but have since had a major headache of variable scope.
该文件的大小使其无法使用,因此我决定拆分为多个模块,但是此后一直困扰着可变范围。 I've largely fixed it (with a fair bit of learning along the way), but I'm keen to understand good structuring to avoid future lessons learnt the hard way.
我已经对其进行了很大程度的修复(在此过程中需要大量学习),但是我渴望了解良好的结构,以避免将来通过艰辛的课程学习。 There are a couple of specific points, but general advice is also welcome.
有几点要点,但也欢迎提供一般性建议。
Modules that need to share the same namespace 需要共享相同名称空间的模块
I have two modules that seem to need to share the same namespace. 我有两个似乎需要共享相同名称空间的模块。 One is the main flow of the program (which transfers data to and from objects, and calls the UI), the other is the UI (which responds to user input, calling the main flow).
一个是程序的主要流程(用于与对象之间的数据传输,并调用UI),另一个是UI(其响应用户输入,称为主要流程)。
Should each of these modules import the other, and then the main file import both? 这些模块中的每个模块都应该导入另一个模块,然后主文件同时导入两个模块吗? That doesn't seem particularly elegant to me.
在我看来,这并不是特别优雅。
from [modulename] import * 从[modulename]导入*
In the answers to this question: 在此问题的答案中:
Python: Sharing global variables between modules and classes therein Python:在其中的模块和类之间共享全局变量
There is a suggestion that from [modulename] import *
should be avoided. 有建议,应避免
from [modulename] import *
。
Is it OK to use from [modulename] import *
to build together a load of modules that just have class definitions? 是否可以使用
from [modulename] import *
来构建仅具有类定义的模块负载? What are "safe" use cases? 什么是“安全”用例?
Modules that need to access each other's namespace is not the same as modules that need to share the same namespace. 需要访问彼此名称空间的模块与需要共享相同名称空间的模块不同。 I can't think of anything you can do with
from modulename import *
that you can't do with import modulename
. 我想不出任何东西,你可以用做
from modulename import *
,你不能用做import modulename
。 You just have to preface a lot of your names with modulename.
您只需要在许多名称前加上
modulename.
That's a good thing, not a bad thing. 那是好事,不是坏事。 It makes your code self-documenting, which is why
from modulename import *
is to be avoided. 它使您的代码可以自我记录,这就是为什么要避免
from modulename import *
原因。
You can have the UI and main flow modules import each other. 您可以使UI和主流模块相互导入。 The only way you'll run into problems is if you reference names between them outside of the scope of functions.
遇到问题的唯一方法是在函数范围之外引用它们之间的名称。 For example
例如
# 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:
...
On the other hand if ui happens to get imported first, then you get the error at theUI = ui.UI()
, when all of mainflow has been interpreted but ui has only been interpreted as far as import mainflow
. 另一方面,如果ui碰巧先被导入,那么当所有主流都已被解释但ui仅被解释为
import mainflow
时,您将在theUI = ui.UI()
处得到错误。 As long as you put all the references to each other inside functions, though, you can get along fine. 但是,只要将所有引用相互放在函数内部,就可以相处得很好。 Eg
例如
# mainflow.py
import ui
...
theUI = None
def initialize():
global theUI
theUI = ui.UI()
There's still a problem with the dependency between the classes; 类之间的依赖关系仍然存在问题。 I recommend you don't do anything like that.
我建议您不要那样做。 But if you did, you could make the whole thing work with this strange approach:
但是,如果您这样做了,则可以使用这种奇怪的方法使整个工作正常进行:
# 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.
Now with the first version of ui.py and the last version of mainflow.py, the program would compile and run. 现在有了ui.py的第一个版本和mainflow.py的最后一个版本,该程序将编译并运行。 I don't really recommend the above;
我真的不推荐上述内容; better organize your code so you don't have such dependencies.
更好地组织您的代码,以便您没有此类依赖项。 But if all you have is calls back and forth between functions in modules, you don't have to resort to such tricks.
但是,如果您只是在模块中的函数之间来回调用,则不必诉诸此类技巧。
There are more object-oriented designy ways to make your UI and your program flow not directly depend on each other, but such a redesign would be more involved than just copy and paste to files and prefacing names with module.
还有更多面向对象的设计方法,可以使UI和程序流不直接相互依赖,但是这样的重新设计将涉及更多的工作,而不仅仅是将其复制和粘贴到文件中以及使用
module.
作为前缀module.
I don't think you want to go overboard with your redesign unless you have a specific reason. 除非有特定原因,否则我认为您不希望过度设计。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.