Python 设计模式,交叉导入
我正在用Python来自动化一个复杂的流程,这个流程有几个选项。我希望在Python中有以下结构:
- 一个“流程类”,里面包含整个流程
- 一个辅助类,里面有很多“黑盒子”(那些不常修改的函数)
99%的时间,我都是在修改流程类的内容,所以我只想在这里放一些经常需要修改的代码,这样我就不用到处滚动去找我想改的代码。这个类还包含一些全局变量(配置设置),这些变量经常会被修改。而辅助类里面的全局变量则不常被修改。
在流程类中,我有一个全局变量,我希望用户在每次运行时都必须输入。代码看起来是这样的:
print ("你想查看调试输出吗(输入 = 否)?")
debug = getUserInput()
这个getUserInput()函数应该放在辅助类中,因为它从来不需要修改。getUserInput需要一个来自流程类的全局变量,这个变量表示用户输入是否应该与Linux命令行或在Windows上运行的Eclipse保持一致。
我的问题是:我该如何最好地组织这个结构?目前的结构看起来是这样的:
import helper_class
isLinux = 1
debug = getUserInput()
辅助类:
import os, flow_class
def getUserInput():
userInput = input ()
if (flow_class.isLinux == 1):
userInput = userInput[:-1]
return userInput
现在因为交叉导入,我遇到了以下错误:
Traceback (most recent call last):
File "flow_class.py", line 1, in <module>
import helper_class
File "helper_class.py", line 1, in <module>
import os, flow_class
File "flow_class.py", line 5, in <module>
debug = getUserInput()
NameError: name 'getUserInput' is not defined
我知道我可以通过总是把isLinux作为参数传递给getUserInput来解决这个问题,但这样会让这个方法的使用变得复杂,也不太直观。
3 个回答
你需要在你的 flow_class
里调用 helper_class.getUserInput()
。这不是关于交叉导入的问题。一旦修复了这个,你会遇到 AttributeError
,这确实和交叉导入有关。
在这个阶段,你需要先实现获取 getUserInput
的逻辑,然后再导入 flow_class
。
关于你最后的说法,我想说的是:你的假设不正确。如果你使用明确的本地值,代码会更清晰。
我知道我可以通过总是把
isLinux
作为参数传给 getUserInput 来解决这个问题,但这样会让这个方法的使用变得复杂,不太直观。
其实,使用全局变量会让这个程序的使用变得比简单的参数复杂得多。
可以试试这样的做法:
debug = getUserInput(isLinux=True)
这里还有一些其他建议:
- 你提到有很多参数会经常改变。这些参数应该硬编码在程序里吗?可以试试使用 配置文件,或者从 'flow' 传递一个字典 (dict) 作为参数。这样你就有一个集中管理的地方,可以轻松修改常用的变量,而不需要深入代码里去找!
- 你的 'flow/helper' 类听起来像是 控制器/模型 的设计模式。这是个好主意。但你的模型不应该去导入你的控制器。
这些建议并不是特别针对“Pythonic 风格”,而是一些通用的编程实践。如果你对程序设计有疑虑,可以看看 《程序员修炼之道》,里面有很多关于工作流程和设计的好建议。还有 《代码大全》,这是 Roberto 推荐的书。