bhe*_*ilr 28 python python-2.7
我正在研究一个相对较大的Python应用程序,并且我希望保留几个资源,因为全局变量可以在几个不同的模块中访问.这些值类似于版本号,版本日期,全局配置以及一些资源的静态路径.我还包含了一个DEBUG
由命令行选项设置的标志,这样我就可以在调试模式下运行我的应用程序而无需完整的环境.
我正在导入的值我一直小心翼翼地确保在运行程序的过程中没有改变的值,并且我将它们记录为不应该触及的全局常量变量.我的代码看起来很像
# Main.py
import wx
from gui import Gui
DEBUG = False
GLOBAL_CONFIG = None
VERSION = '1.0'
ICON_PATH = 'some/path/to/the/app.ico'
def main():
global DEBUG, GLOBAL_CONFIG
# Simplified
import sys
DEBUG = '--debug' in sys.argv
GLOBAL_CONFIG = load_global_config()
# Other set-up for the application, e.g. setting up logging, configs, etc
app = wx.App()
gui = Gui()
app.MainLoop()
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
# gui.py
import wx
from __main__ import DEBUG, GLOBAL_CONFIG, ICON_PATH
import controller
class Gui(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None)
icon = wx.Icon(ICON_PATH, wx.BITMAP_TYPE_ICO)
self.SetIcon(icon)
# Always make a copy so we don't accidentally modify it
conf = GLOBAL_CONFIG.copy()
self.controller = controller.Controller(conf)
# More setup, building the layout, etc
Run Code Online (Sandbox Code Playgroud)
# controller.py
from __main__ import DEBUG
import logging
log = logging.getLogger('controller')
class Controller(object):
def __init__(self, conf):
if DEBUG:
log.info("Initializing controller in DEBUG mode")
self.conf = conf
# Other setup ...
Run Code Online (Sandbox Code Playgroud)
这显然远远落后于我的应用程序实际上,并且忽略了错误处理,文档以及基本上所有实现细节.
现在,我已经看到它说这是一个坏主意,但没有解释为什么.由于大多数搜索"python import __main__"变体的结果都是关于什么的问题if __name__ == '__main__'
,因此很难找到关于这个主题的一些可靠信息.到目前为止,我没有任何问题,它实际上非常方便.
那么这被认为是很好的Python实践,还是有理由我应该避免这种设计?
Hen*_*ter 26
我认为有两个主要(哈哈)原因可能会规定避免这种模式.
如果你有以上的应用程序总量控制,并永远不会有另一个切入点或其他使用您的功能,并且你确定你不介意的不确定性,我不认为有任何客观理由的from __main__ import foo
模式是不好的.我个人不喜欢它,但同样,它基本上是出于上述两个原因.
我认为一个更强大/开发人员友好的解决方案可能是这样的,创建一个专门用于保存这些超全局变量的特殊模块.然后,您可以导入模块并module.VAR
在需要设置时随时查阅.本质上,只需创建一个特殊的模块命名空间,用于存储超全局运行时配置.
# conf.py (for example)
# This module holds all the "super-global" stuff.
def init(args):
global DEBUG
DEBUG = '--debug' in args
# set up other global vars here.
Run Code Online (Sandbox Code Playgroud)
然后你会更像这样使用它:
# main.py
import conf
import app
if __name__ == '__main__':
import sys
conf.init(sys.argv[1:])
app.run()
Run Code Online (Sandbox Code Playgroud)
# app.py
import conf
def run():
if conf.DEBUG:
print('debug is on')
Run Code Online (Sandbox Code Playgroud)
注意使用conf.DEBUG
而不是from conf import DEBUG
.这种结构意味着您可以在程序的生命周期中更改变量,并将该更改反映在其他地方(显然,假设单个线程/进程).
另一个好处是,这是一个相当普遍的模式,因此其他开发人员将很容易认识到它.它很容易与settings.py
各种流行应用程序(例如django
)使用的文件相媲美,但我避免使用该特定名称,因为settings.py
它通常是一堆静态对象,而不是运行时参数的命名空间.上面描述的配置命名空间模块的其他好名称可以是runtime
或者params
例如.
归档时间: |
|
查看次数: |
21172 次 |
最近记录: |