我正在编写一个名为 Foo 的库作为示例。
__init__.py
文件:
from .foo_exceptions import *
from .foo_loop import FooLoop()
main_loop = FooLoop()
from .foo_functions import *
__all__ = ['main_loop'] + foo_exceptions.__all__ + foo_functions.__all__
安装后,可以像这样使用:
# example A
from Foo import foo_create, main_loop
foo_obj = foo_create()
main_loop().register(foo_obj)
或者像这样:
# example B
import Foo
foo_obj = Foo.foo_create()
Foo.main_loop().register(foo_obj)
我显然更喜欢B方法。没有名称冲突,并且明确说明了每个外部对象的来源。
这么多介绍,现在我的问题。在这个库中,我需要从不同的文件中导入一些东西。同样,我有几种方法可以做到这一点。问题是哪种风格更喜欢 - C,D还是E?请阅读以下内容。
# example C
from . import foo_exceptions
raise foo_exceptions.FooError("fail")
或
# example D
from .foo_exceptions import FooError
raise FooError("fail")
或
# example E
from . import FooError
raise FooError("fail")
方法C的缺点是,导入整个模块而不是仅导入一些必需的对象会增加循环导入问题的可能性。还要考虑这一行:
from . import foo_exceptions, main_loop
它看起来像是从一个来源导入2个符号,但它不是。前者(foo_exceptions
)是当前目录中的模块(.py文件),后者是__init__.py
中定义的对象。
这就是为什么我没有使用C风格,而最终形式的问题是:D或E(以及为什么)?
(感谢您阅读这个长问题。所有代码片段仅为示例,可能包含拼写错误)
在alexanderlukanin的回答之后:
from .module import symbol
形式。答案 0 :(得分:0)
不要使用旧式relative imports:
# Import from foo/foo_loop.py
# This DOES NOT WORK in Python 3
# and MAY NOT WORK AS EXPECTED in Python 2
from foo_loop import FooLoop
# This is reliable and unambiguous
from .foo_loop import FooLoop
除非确实必须使用星号导入,否则不要使用星号导入。
# Namespace pollution! Name clashes!
from .submodule import *
不要使用前缀 - 您已完全为此目的获得了名称空间。
# Unpythonic
from foo import foo_something_create
foo_something_create()
# Pythonic
import foo.something
foo.something.create()
您的软件包的API必须定义明确。你的实现不能太纠结。其余的是品味问题。
# [C] This is good.
# Import order: __init__.py, exceptions.py
from . import exceptions
raise exceptions.FooError
# [D] This is also fine.
# Import order is the same as above,
# only name binding inside the current module is different.
from .exceptions import FooError
raise FooError
# [E] This is not as good because it adds one unnecessary level of indirection
# submodule.py -> __init__.py -> exceptions.py
from . import FooError
raise FooError