2

我想使用 __init__.py 将包中的所有模块作为别名导入 __main__ 中,以便可以简单地从交互模式调用它们。例如,这是一个示例文件树:

foobar/
    __init__.py
    foo.py
    bar.py

从python解释器我希望能够导入包并使用定义的别名访问所有模块,如下所示:

>>> import foobar
>>> <module 'foobar' from 'C:\...'>
>>> f.func()
>>> b.func()

这将要求 __init__.py 包含以下内容:

# __init__.py

from . import foo as f
from . import bar as b

# these will not work
__main__.f = f
__main__.b = b

我怎样才能使这项工作?

编辑

我不想使用from foobar import *,因为它不允许我使用别名。

from foobar import foo as f每次我启动交互模式时,为每个模块都打字效率不高,因为可能有数百个模块。

4

3 回答 3

3

在您的 __init__.py 文件中包含以下内容:

import foo
import bar as b

然后在交互式会话中使用:

>>> from foobar import *
>>> value = foo.some_func()
>>> instance = b.SomeClass()

我还应该提到,from foobar import *大多数 python 程序员都认为这是不好的风格,虽然这在交互式会话中并不重要,但如果你想在模块或脚本中完成同样的事情,首选的方式是:

from foobar import b, foo
于 2012-10-26T16:18:28.790 回答
1

如果一个模块在没有被明确告知这样做的情况下将内容添加到单独的模块的命名空间中,那将是非常糟糕的行为。正如他们所说,显式优于隐式。

我建议您避免使用任何复杂的内容__init__.py,只需在主模块(或命令行)中执行此操作:

import foobar.foo as f, foobar.bar as b

编辑:

如果您确实需要,可以弄乱主模块。虽然这可能不是一个好主意,但方法如下:

import sys

import foo, bar

main = sys.modules["__main__"]
main.f = foo
main.b = bar

现在,正如一些人所说,让导入模块产生这样的副作用通常不是一个好主意。至少,任何读过你的代码的人都会非常困惑。“等等,这个f变量是从哪里来的?”

我建议不要让你的模块将东西插入到你的全局命名空间中,而是让它在它自己的命名空间中做你想要的别名,然后在它上面使用from module import *它来获取你的命名空间中的别名。

Makefoobar__init__.py文件如下所示:

from . import foo as f
from . import bar as b

然后在您的主模块中,只需执行以下操作:

from foobar import *
# now you can use f and b

如果您有数百个导入要做,请将它们全部放入__init__.py. 或者,如果它们与该包无关,请使用单独的模块来处理别名内容。

于 2012-10-26T17:58:35.417 回答
0

根本没有指定 Python 模块像那样突破其命名空间,并且因为 Python 有效地倾向于限制通常不是一个好主意的所有内容,所以这是不可能的。交互式控制台可能有启动钩子之类的东西,谁知道呢。

另一个可以让您的生活更轻松的想法:在模块中写入:

foo = "foo!"
bar = "bar!"

def add_to(obj):
    obj['f'] = foo
    obj['b'] = bar

在您的交互式控制台中:

>>> from stuff import add_to
>>> add_to(globals())
于 2012-10-26T19:25:39.373 回答