导入与模块同名的类/函数

时间:2017-05-19 07:51:55

标签: python python-3.x python-import

假设我使用具有以下结构的python包:

package/
   bar.py
   foo.py
   __init__.py

bar.py包含课程barfoo.py包含函数foo。 当我想导入函数/类时,我必须写

from package.bar import bar
from package.foo import foo

或者我可以写

from package import bar
from package import foo

更普遍的问: 当我导入一个与类/函数同名的模块时,我是否可以省略类/函数名称?

1 个答案:

答案 0 :(得分:3)

不,您不能省略模块或对象名称。没有任何机制可以隐含地进行此类导入。

来自Zen of Python

  

明确比隐含更好。

请注意,导入模块本身也应始终是有效选项。如果from package import bar导入了package.bar.bar对象,那么您必须尽量让自己访问package.bar模块。

此外,这种隐式行为(自动导入模块中包含的对象而不是模块本身)会导致混淆不一致。

  • import package.bar添加到命名空间的内容是什么?引用package.bar是模块还是包含的对象?
  • 重命名包含的对象时,导入此类名称的代码会发生什么变化?然后from package import bar会给你模块吗?某些操作仍然会成功,导致奇怪的,难以调试的错误,而不是明确的ImportError异常。

一般来说,Python模块很少只包含一个的东西。 Python不是Java,模块由密切相关的对象组组成,而不仅仅是一个类或函数。

现在,包中存在固有的命名空间冲突; from package import foo可以将package模块,上设置的名称引用到嵌套模块名称。在这种情况下,Python将首先查看package命名空间。

这意味着您可以明确决定在foo中的包级别提供barpackage/__init__.py个对象:

# in package/__init__.py
from .foo import foo
from .bar import bar

现在from package import foofrom package import bar将为您提供这些对象,屏蔽嵌套模块。

将子模块中的对象导入包命名空间的一般机制是组合公共API的常用方法,同时仍使用内部模块对逻辑进行分组。例如,Python标准库中的json.JSONDecodeError exceptionjson.exceptions模块中定义,然后导入json/__init__.py。我通常会阻止屏蔽子模块;但是foobar加入了一个名称不同的模块。