gpt4 book ai didi

python - 为什么 Python 的 __import__ 需要 fromlist?

转载 作者:IT老高 更新时间:2023-10-28 21:33:56 32 4
gpt4 key购买 nike

在 Python 中,如果你想以编程方式导入模块,你可以这样做:

module = __import__('module_name')

如果你想导入一个子模块,你会认为这很简单:

module = __import__('module_name.submodule')

当然,这是行不通的;您只需再次获得 module_name 。你必须这样做:

module = __import__('module_name.submodule', fromlist=['blah'])

为什么? fromlist 的实际值似乎根本不重要,只要它不为空。要求一个参数,然后忽略它的值有什么意义?

Python 中的大多数东西似乎都是有充分理由的,但就我的一生而言,我无法为这种行为的存在提出任何合理的解释。

最佳答案

其实__import__()的行为完全是因为调用了__import__()import语句的实现。 import 调用 __import__() 基本上有五种略有不同的方式(主要有两个类别):

import pkg
import pkg.mod
from pkg import mod, mod2
from pkg.mod import func, func2
from pkg.mod import submod

在第一种第二种情况下,import 语句应该将“最左边”的模块对象分配给“最左边”的名称:。在 import pkg.mod 之后你可以做 pkg.mod.func() 因为 import 语句引入了本地名称 pkg,它是一个具有 mod 属性的模块对象。因此,__import__() 函数必须返回“最左边”的模块对象,以便将其分配给 pkg。因此,这两个 import 语句转换为:

pkg = __import__('pkg')
pkg = __import__('pkg.mod')

在第三种、第四种和第五种情况下,import 语句必须做更多的工作:它必须分配(可能)多个名称,这些名称必须从模块对象中获取。 __import__() 函数只能返回一个对象,并且没有真正的理由让它从模块对象中检索每个名称(这会使实现变得更加复杂。)所以简单的方法类似于(对于第三种情况):

tmp = __import__('pkg')
mod = tmp.mod
mod2 = tmp.mod2

但是,如果 pkg 是一个包,并且 modmod2 是该包中的模块 尚未导入,因为它们在第三种和第五种情况下。 __import__() 函数需要知道 modmod2import 语句想要拥有的名称可访问,以便它可以查看它们是否是模块并尝试导入它们。所以调用更接近:

tmp = __import__('pkg', fromlist=['mod', 'mod2'])
mod = tmp.mod
mod2 = tmp.mod2

这会导致 __import__() 尝试加载 pkg.modpkg.mod2 以及 pkg (但如果 modmod2 不存在,则在 __import__() 调用中不是错误;产生错误留给import 语句。)但这仍然不是第四个和第五个示例的正确方法,因为如果调用是这样的:

tmp = __import__('pkg.mod', fromlist=['submod'])
submod = tmp.submod

然后 tmp 最终会像以前一样成为 pkg,而不是您想要获取 pkg.mod 模块submod 属性来自。实现可能已经决定这样做,所以 import 语句做了额外的工作,在 . 上拆分包名称,就像 __import__() 函数一样确实并遍历名称,但这意味着重复一些工作。因此,相反,实现使 __import__() 返回 right-most 模块而不是 left-most 一个 if and only如果 fromlist 已通过且不为空。

(import pkg as pfrom pkg import mod as m 语法不会改变这个故事的任何内容,除了分配给哪些本地名称 - __import__() 函数在使用 as 时没有什么不同,它都保留在 import 语句实现中。)

关于python - 为什么 Python 的 __import__ 需要 fromlist?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2724260/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com