导入与模块同名的 classes/functions
Importing classes/functions with same name as module
假设我使用具有以下结构的 python 包:
package/
bar.py
foo.py
__init__.py
bar.py
包含 class bar
并且 foo.py
包含函数 foo
。
当我想导入 function/class 时,我必须写
from package.bar import bar
from package.foo import foo
或者我可以写
from package import bar
from package import foo
更普遍的问题:
当我导入与 class/function 同名的模块时,是否可以始终省略 class/function 名称?
不,您不能省略模块或对象名称。没有任何机制可以隐式执行此类导入。
Explicit is better than implicit.
请注意,导入 模块本身 也应该始终是一个有效的选项。如果 from package import bar
导入了 package.bar.bar
对象,那么您将不得不费尽心思才能访问 package.bar
模块本身。
此外,这种隐式行为(自动导入模块中包含的对象而不是模块本身)会导致令人困惑的不一致。
import package.bar
为您的命名空间添加了什么?引用 package.bar
是模块还是包含的对象?
- 当您重命名所包含的对象时,导入此类名称的代码会发生什么情况?
from package import bar
然后给你模块吗?一些操作仍然会成功,导致奇怪的、难以调试的错误,而不是明确的 ImportError
异常。
一般来说,Python 模块很少只包含 一个 东西。 Python 不是 Java,模块由密切相关的对象组组成,而不仅仅是一个 class 或函数。
现在,包中存在固有的名称空间冲突; from package import foo
可以引用在 package
模块上设置的名称, 或 可以引用嵌套的模块名称。在这种情况下,Python 将首先查看 package
命名空间。
这意味着您可以明确决定在包级别提供foo
和bar
对象,在package/__init__.py
中:
# in package/__init__.py
from .foo import foo
from .bar import bar
现在 from package import foo
和 from package import bar
将为您提供那些对象,屏蔽嵌套模块。
将对象从子模块导入包命名空间的一般机制是编写 public API 同时仍使用内部模块对代码进行逻辑分组的常用方法。例如Python标准库中的json.JSONDecodeError
exception是在json.exceptions
模块中定义的,然后导入到json/__init__.py
中。但是,我通常不鼓励屏蔽子模块;但是 foo
和 bar
进入了具有不同名称的模块。
假设我使用具有以下结构的 python 包:
package/
bar.py
foo.py
__init__.py
bar.py
包含 class bar
并且 foo.py
包含函数 foo
。
当我想导入 function/class 时,我必须写
from package.bar import bar
from package.foo import foo
或者我可以写
from package import bar
from package import foo
更普遍的问题: 当我导入与 class/function 同名的模块时,是否可以始终省略 class/function 名称?
不,您不能省略模块或对象名称。没有任何机制可以隐式执行此类导入。
Explicit is better than implicit.
请注意,导入 模块本身 也应该始终是一个有效的选项。如果 from package import bar
导入了 package.bar.bar
对象,那么您将不得不费尽心思才能访问 package.bar
模块本身。
此外,这种隐式行为(自动导入模块中包含的对象而不是模块本身)会导致令人困惑的不一致。
import package.bar
为您的命名空间添加了什么?引用package.bar
是模块还是包含的对象?- 当您重命名所包含的对象时,导入此类名称的代码会发生什么情况?
from package import bar
然后给你模块吗?一些操作仍然会成功,导致奇怪的、难以调试的错误,而不是明确的ImportError
异常。
一般来说,Python 模块很少只包含 一个 东西。 Python 不是 Java,模块由密切相关的对象组组成,而不仅仅是一个 class 或函数。
现在,包中存在固有的名称空间冲突; from package import foo
可以引用在 package
模块上设置的名称, 或 可以引用嵌套的模块名称。在这种情况下,Python 将首先查看 package
命名空间。
这意味着您可以明确决定在包级别提供foo
和bar
对象,在package/__init__.py
中:
# in package/__init__.py
from .foo import foo
from .bar import bar
现在 from package import foo
和 from package import bar
将为您提供那些对象,屏蔽嵌套模块。
将对象从子模块导入包命名空间的一般机制是编写 public API 同时仍使用内部模块对代码进行逻辑分组的常用方法。例如Python标准库中的json.JSONDecodeError
exception是在json.exceptions
模块中定义的,然后导入到json/__init__.py
中。但是,我通常不鼓励屏蔽子模块;但是 foo
和 bar
进入了具有不同名称的模块。