6

我想创建一个像 NumPy 一样工作的 Python 模块。这些方法不仅是模块源树的叶子中的子模块。有一个根模块包含许多我可以直接调用的方法,还有子模块。问题是必须在某处定义根方法。我在想有一个目录结构:

module/
  __init__.py
  core.py
  stuff1.py
  submodule/
    __init__.py
    stuff2.py
    stuff3.py

现在我想要将“core”中的所有内容导入“module”命名空间,就好像它是一个module.py文件一样,并且core.py的内容在这个module.py中。问题是模块是一个目录而不是一个文件,那么我该如何定义这些应该位于模块根目录中的方法呢?

我尝试在init .py 中放入“from core import *” ,但这没有用。(编辑:实际上确实如此。)

我是否应该在“module.py”文件中包含核心方法以及模块目录?我不知道这是否有效,但它看起来很尴尬。

4

2 回答 2

5

我认为你想要的是能够做到这一点:

# 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!

当你 import 时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 *and/or一起正常工作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)以表明没有理由再从包外部触摸它。

# some_other_script.py

from module import *

print core_func() # Prints 1
print mod_func() # Prints 2
于 2013-03-11T23:59:10.720 回答
3

查看有关__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
于 2013-03-11T20:21:38.610 回答