python模块/包共享

时间:2015-04-17 16:03:58

标签: python python-2.7 module packages

我有一个使用自定义模块功能的烧瓶应用程序。

我的文件层次结构如下:

__init__.py
    ec2/__init__.py
    citrixlb/__init__.py

到目前为止,在根__init__.py中我有一个from ec2 import *子句来加载我的模块。

现在我添加了一项新功能'叫做citrixlb。

citrixlb和ec2中的__init__.py文件都使用一些相同的功能来完成任务。

我在想做类似的事情:

__init__.py
    common/__init__.py
    ec2/__init__.py
    citrixlb/__init__.py

如果我执行上述操作,并将所有常用功能移至common/__init__.pyec2/__init__.pycitrixlb/__init__.py将如何访问这些功能 在common/__init__.py

原因是

  • 我想让根__init__.py尽可能稀疏
  • 我希望能够在__init__.pycitrixlb中运行ec2 独立脚本。
  • 我还希望能够通过添加newdir/__init__.py
  • 继续添加功能

1 个答案:

答案 0 :(得分:1)

  

如果我执行上述操作,并将所有常用功能移至common/__init__.pyec2/__init__.pycitrixlb/__init__.py如何访问common/__init__.py中的功能?

这正是explicit relative imports的设计目标:

from .. import common

或者,如果您坚持使用import *

from ..common import *

您可以使用绝对导入来执行此操作。假设您的顶级包名为mything

from mything import common
from mything.common import *

但在这种情况下,我认为相对版本你会更好。它不仅更简洁,更易于阅读,更强大(如果您重命名mything,或重新组织其结构,或将整个包嵌入更大的包中......)。但是你可能想要阅读PEP 328中两个不同特征的基本原理来决定哪一个在这里对你更有吸引力。


有一件事:

  

我希望能够以__init__.pycitrixlb作为独立脚本运行ec2

那,你做不到。作为顶级脚本在包内运行模块不应该工作。有时你会逃脱它。一旦你从兄弟姐妹或父母那里进口,你肯定不会逃脱它。

正确的方法是:

  • python -m mything.ec2代替python mything/ec2/__init__.py
  • 在顶层写一个简单的ec2脚本,就像from mything.ec2 import main; main()一样。

后者是一种常见的模式,如果您正在构建setuptools发行版,它可以自动为您构建ec2脚本。当ec2包裹在您的/usr/local/bin中时,即使mything site-packages结束,也会自动使其仍然有效。有关详细信息,请参阅console_scripts