Python:从已经导入的模块中导入函数

3
假设我有一个名为my_package的Python包,其中包含一个名为my_module的模块和一个名为my_function的函数。

我试图在Python交互式shell中执行以下导入操作:

>>> from my_package import my_module
>>> my_module.my_function()            # => OK
>>> from my_module import my_function  # => ImportError: No module named my_module
>>> from my_package.my_module import my_function   # => OK

我对上面第三行的ImportError感到非常惊讶:因为my_module已经被导入,为什么我不能从中导入一个函数呢?也许我对Python导入系统的工作方式有些误解,任何澄清都将不胜感激!


以下是目录结构和源代码。

my_package
  |- __init__.py
  |- my_module.py

这是 __init__.py 文件

all = ["my_module"]

这里是 my_module.py 文件

def my_function():
    pass
1个回答

4
Python的导入系统并不是这样工作的。当你使用 from foo import bar 时,foo 必须是一个“真正的”,完全合格的包或模块名称(或者是使用点号的相对名称)。也就是说,它必须是你可以在普通的 import foo 中使用的东西。它不能仅仅是你随意创建的一个模块对象。例如,你也不能这样做:
import foo as bar
from bar import someFunction

这在文档中有说明,但您需要阅读该部分以获得完整的图片。它说:
导入语句分两个步骤执行:(1)找到一个模块,并根据需要对其进行初始化;(2)在本地命名空间(发生导入语句的作用域)中定义一个或多个名称。该语句有两种形式,它们不同之处在于是否使用from关键字。第一种形式(不含from)为列表中的每个标识符重复这些步骤。使用from的形式执行第(1)步一次,然后重复执行第(2)步。
第(1)步是“查找模块”,如果您继续阅读,您将看到这是其在sys.modulessys.path等中查找的过程。没有任何时候,它会在导入命名空间中寻找名称,而恰好这个名称有一个模块对象作为其值。请注意,两种类型的导入的模块查找过程并无不同;当您执行import foofrom foo import bar时,它查找foo的方式是相同的。如果普通的import my_module不起作用(就像您的示例一样),那么from my_module import stuff也不会起作用。
请注意,如果您已经导入了模块,并且只想为其中的一个函数指定一个更短的名称,则可以将常规变量分配给该函数。
from my_package import my_module
myfunc = my_module.my_function

2
Python的导入系统基本上并不是那么好。而且这也已经在官方文档中说明了。 - Jürgen A. Erhard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接