假设我有一个模块foo和一个子模块foo.bar。如果要在中使用方法foo.bar,我是否需要foo.bar直接导入还是foo足够导入?
foo
foo.bar
例如,以下引发错误:
import foo foo.bar.my_method()
和以下作品:
import foo.bar foo.bar.my_method()
但是我不确定这是否通常是需要的,或者我的代码本身是否有问题。(我认为通常需要直接导入子模块…但是我可能发誓我看到没有直接导入子模块的代码仍然可以正常工作。)
如果要在中使用方法foo.bar,我是否需要foo.bar直接导入还是foo足够导入?
您需要显式导入子模块。执行import foo.bar将自动导入父模块foo,并且必须†绑定名称foo,但反之则不正确。
import foo.bar
但是我可能发誓我看到了没有直接导入但仍然可以正常工作的代码
是。有时,无需显式导入即可访问子模块。当父模块本身导入子模块时,就会发生这种情况。除非有文档说明,否则切勿依赖它,因为它可能是实现细节,并且在库版本升级后可能会更改而不会发出警告。
作为展示 这两种 行为的流行图书馆的示例,请参阅requests==2.18.4。该程序包具有称为sessions和的子模块help(以及其他子模块)。导入requests将requests.sessions隐式可用,但是requests.help直到显式导入才可用。当执行初始化包的源代码,你会发现该sessions子模块导入的数据,但help子模块没有。
requests==2.18.4
sessions
help
requests
requests.sessions
requests.help
† 这是有道理的,因为后续的使用foo.bar需要对现有foo对象进行属性访问。请注意,from foo.bar import something并 没有 绑定的名称foo,也没有foo.bar,尽管这两个模块foo和foo.bar进口和缓存到sys.modules。
from foo.bar import something
sys.modules