如何在__init__.py中导入包模块为__main__别名?

时间:2012-10-26 16:03:24

标签: python

我想使用__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,每次启动交互模式都不高效,因为可能有数百个模块。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

模块将事物添加到单独模块的命名空间而不明确告知这样做是非常糟糕的行为。 Explicit is better than implicit正如他们所说的那样。

我建议你在__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 *来获取命名空间中的别名

foobar的{​​{1}}文件看起来像这样:

__init__.py

然后在主模块中,执行:

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

如果要进行数百次导入,请将它们全部放在from foobar import * # now you can use f and b 中。或者,如果它们与该包没有关联,请使用单独的模块来处理别名。

答案 2 :(得分: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())