【发布时间】:2012-01-07 21:48:57
【问题描述】:
我有一个名为spellnum 的模块。它可以用作命令行实用程序(它具有 if __name__ == '__main__': 块),也可以像标准 Python 模块一样导入。
该模块定义了一个名为Speller 的类,如下所示:
class Speller(object):
def __init__(self, lang="en"):
module = __import__("spelling_" + lang)
# use module's contents...
如您所见,类构造函数在运行时加载其他模块。这些模块(spelling_en.py、spelling_es.py 等)与spellnum.py 本身位于同一目录中。
除了spellnum.py,还有其他一些具有实用功能和类的文件。我想隐藏这些文件,因为我不想将它们暴露给用户,而且用随机文件污染 Python 的 lib 目录是个坏主意。据我所知,实现这一目标的唯一方法是创建一个包。
我为这个项目设计了这个布局(灵感来自这个伟大的tutorial):
spellnum/ # project root
spellnum/ # package root
__init__.py
spellnum.py
spelling_en.py
spelling_es.py
squash.py
# ... some other private files
test/
test_spellnum.py
example.py
文件__init__.py 包含一行:
from spellnum import Speller
鉴于这种新布局,必须更改动态模块加载的代码:
class Speller(object):
def __init__(self, lang="en"):
spelling_mod = "spelling_" + lang
package = __import__("spellnum", fromlist=[spelling_mod])
module = getattr(package, spelling_mod)
# use module as usual
因此,使用此项目布局 a 可以执行以下操作:
-
成功地将
import spellnum放入example.py并像简单模块一样使用它:# an excerpt from the example.py file import spellnum speller = spellnum.Speller(es) # ... -
import spellnum在测试中并从项目根目录运行这些测试,如下所示:$ PYTHONPATH="`pwd`:$PYTHONPATH" python test/test_spellnum.py
问题
我无法使用新布局直接执行spellnum.py。当我尝试时,它显示以下错误:
Traceback (most recent call last):
...
File "spellnum/spellnum.py", line 23, in __init__
module = getattr(package, spelling_mod)
AttributeError: 'module' object has no attribute 'spelling_en'
问题
组织我的模块工作所需的所有文件以便用户能够从命令行和 Python 代码使用模块的最佳方式是什么?
谢谢!
【问题讨论】:
标签: python dynamic module package