修复python的坏的行为的例程。
demain的Python项目详细描述
这个包为您想要的情况提供了一个干净的解决方案 编写一个可以从命令行安全调用的python模块 但也需要其他模块导入。简单地写下每一个 通常会生成__name__==^{tt3}的模块$ 改为这样检查:
'Your module docstring' import demain __main__ = demain.fix() # Your other import statements # Your classes and functions if __main__: # Your code that gets invoked from the command line
如果您的模块只是被另一个模块导入, 函数fix()什么也不做,返回False。但是如果你的 模块已被直接调用,可以作为脚本调用,也可以使用python的 -m选项,然后fix()将:
- 用模块的真实名称替换模块的__name__全局变量。
- 在sys.modules中以模块的真名重新注册模块,以便 稍后其他python模块的import语句可以找到它。
- 如果模块位于包的下面,则将模块插入 以其正确名称命名的包。
- 在进行这些更正之后,函数返回True,以便 您的模块可以检测到它作为主程序运行。
我主张未来版本的python停止破坏模块名 在每个模块中设置一个__main__boolean 德马因确实如此。但在此之前,请使用demain将您的程序 一些理智,安全,少一些神秘的中断和错误信息。
背景
从命令行运行python脚本或调用模块时 使用-m选项,python为该脚本或模块提供假 名称'__main__',以便它能够检测到它作为 “main program.”考虑一个小脚本,如下所示:
# foo.py print __name__
从命令行调用它会删除正常的fooname 如果不是这样的话(我们可以证明,通过导入 命令行中的模块):
$ python foo.py __main__ $ python -m foo __main__ $ python -c 'import foo' foo
此名称损坏在与 它们本身就是进口的目标,因为 以实名导入模块会导致 正在创建模块,每个对象和类都有自己的副本。这个 这导致的漏洞往往特别难以追踪。
demain.fix()函数的设计目的是防止此问题 即使是一开始,你第一次打电话给 要直接调用的每个模块。小心不要 只是为了避免在运行fix()之前执行其他导入,但是 还要确保首先不创建类;否则,名称 '__main__'将作为其模块名复制到您的类中。
我知道当我读到 保护金字塔的设计,并达到克里斯·麦克唐纳的痛苦 在标题为“应用程序程序员不能控制 模块范围代码路径。“
http://docs.pylonshq.com/pyramid/dev/designdefense.html
在那里,他对python的长期经验和他经过严格磨练的编码 实践使他对 小python应用程序——特别是那些 使用web微框架-当他们将脚本视为 是一个正常的模块。我希望demain能解决这个问题 使调用的python脚本成为对象的安全位置, 而不是在同一个python文件 使用普通导入从应用程序中的其他位置导入。
这个包附带了一个适度的测试套件,它是由几个手工构建的 示例,以及McDonough的示例decorator框架 python处理脚本调用的问题。运行它, 只需键入:
$ python -m demain.tests