我想创建一个像NumPy一样工作的Python模块。这些方法不仅是模块源树中树叶的子模块。有一个根模块包含我可以直接调用的许多方法,还有子模块。问题是必须在某处定义根方法。我想要有一个目录结构:
module/
__init__.py
core.py
stuff1.py
submodule/
__init__.py
stuff2.py
stuff3.py
现在我想要将“core”中的所有内容导入到“module”命名空间中,就好像它是一个module.py文件,而core.py的内容都在这个module.py中。问题是模块是目录而不是文件,那么如何定义应该位于模块根目录中的这些方法呢?
我尝试将“from core import *”放在 init .py中,但这不起作用。 (编辑:实际上确实如此。)
我是否应该在“module.py”文件中包含核心方法,还有模块目录?我不知道这是否有效,但看起来很尴尬。
答案 0 :(得分:4)
我认为你想要的是能够做到这一点:
# some_other_script.py
import module
# Do things using routines defined in module.core
当您向Python import module
询问时(在非常基本意义上),运行module/__init__.py
并创建module
对象时会发生什么导入到您的命名空间。此对象(同样,非常基本)包含运行__init__.py
时发生的事情:名称定义等。这些可以通过module.something
访问。
现在,如果你的设置如下:
# module/__init__.py
from module.core import Clazz
c = Clazz()
print c # Note: demo only! Module-level side-effects are usually a bad idea!
导入module
时,您会看到如下的打印语句:
<module.core.Clazz object at 0x00BBAA90>
大。但是,如果您尝试访问c
,则会获得NameError
:
# some_other_script.py
import module # prints "<module.core.Clazz object at 0x00BBAA90>"
print c # NameError (c is not defined)
这是因为你没有导入c
;您已导入module
。相反,您的入口点脚本如下所示:
# some_other_script.py
import module # prints "<module.core.Clazz object at 0x00BBAA90>"
print module.c # Access c *within module*
一切都会好起来的。这将也与from core import *
和/或from module import *
一起正常工作,但我(和PEP8)建议反对,因为当你不清楚脚本中发生了什么开始用野生进口来解决问题。为清楚起见:
# module/core.py
def core_func():
return 1
# module/__init__.py
from core import *
def mod_func():
return 2
上面的内容确实相当不错,不过您也可以将core
设为“私有”(重命名为_core
),以表示没有理由再从包装外部触摸它。< / p>
# some_other_script.py
from module import *
print core_func() # Prints 1
print mod_func() # Prints 2
答案 1 :(得分:2)
查看有关__all__
列表的信息。它允许您定义导出的名称。
标记它,您可以设置一个函数来确定从子模块中提取的内容:
@property
all(self):
#Whatever introspective code you may want for your modules
__all__ += submodule.__all__
如果你只想在模块空间中使用该死的shabang,这是一种方式:
$ ipython
In [1]: from foomod import *
In [2]: printbar()
Out[2]: 'Imported from a foreign land'
In [3]: ^D
Do you really want to exit ([y]/n)?
$ ls foomod/
__init__.py __init__.pyc core.py core.pyc submodule
$ grep . foomod/*.py
foomod/__init__.py:from foomod.core import *
foomod/core.py:def printbar():
foomod/core.py: return "Imported from a foreign land"
...如果我们让__init__.py
为空:
$ echo > foomod/__init__.py
$ ipython
In [1]: from foomod import *
In [2]: printbar()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-2-ba5b6693441e> in <module>()
----> 1 printbar()
NameError: name 'printbar' is not defined