python为什么import不了_为什么Python的__import__需要fromlist?

本文深入探讨了Python中动态导入模块的方法及内部原理,特别是__import__函数的使用及其fromlist参数的作用。

在Python中,如果要以动态方式导入模块,可以执行以下操作:module = __import__('module_name')

如果要导入子模块,你可能认为这只是一个简单的问题:module = __import__('module_name.submodule')

结果呢,当然不起作用了,你必须这么做:module = __import__('module_name.submodule', fromlist=['xxx'])

为什么?实际值fromlist似乎根本不重要,只要它不是空的就行。

实际上,__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语句将最左侧模块对象分配给了: pkg。之后的import pkg.mod可以这样使用pkg.mod.func(),因为import语句引入了本地的模块pkg,这是一个具有mod属性的模块对象。因此__import__函数必须返回最左侧的模块对象,以便将其分配给pkg。这两种情况相当于pkg = __import__('pkg')

pkg = __import__('pkg.mod')

后面三种情况,import就必须做更多的工作了,它必须从模块对象获取并分配多个名称。但是__import__函数只能返回一个对象,并且它不能从模块对象中检索出多个名字,所以对于第三种情况就是:pkg = __import__('pkg')

mod = pkg.mod

mod2 = pkg.mod2

但是如果mod和mod2在该模块pkg中尚未导入,那将无法生效。__import__函数需要知道mod和mod2是它可以访问的名称,以便它可以查看他们是否是模块并且尝试导入他们。所以像一下这个方式更为接近:pkg = __import__('pkg', fromlist=['mod', 'mod2'])

mod = pkg.mod

mod2 = pkg.mod2

这会导致__import__先尝试pkg.mod和pkg.mod2,如果不生效的话,它并不会抛出异常。但是第五种例子按照以上方式依然不行:tmp = __import__('pkg.mod', fromlist=['submod'])

submod = tmp.submod

我们希望tmp是pkg.mod模块,但实际上它还是pkg模块。如果是按照我们想的这种方式去加载,那就要增加更多额外的解包工作。所以它就直接返回了最右边的模块,当且仅当fromlist里面不是空的时候。

总结

__import__函数中的fromlist实际上是没有具体含义的,你可以理解为它只是一种标记,当它不为空的时候,import将为我们导入前面所写的字符串中最右边的模块。当它为空的时候,import将为我们导入字符串最左边的模块,仅此而已。

### Python 中 `__import__` 函数的用法 在 Python 编程语言中,内置函数 `__import__()` 提供了一种动态导入模块的方式。通常情况下,开发者会使用更直观的 `import` 语句来加载模块;然而,在某些特殊场景下,比如当模块名称作为字符串传递或者需要执行复杂的导入逻辑时,则可以考虑采用此方法。 #### 基本语法结构 该函数接受多个参数,其中第一个必选参数是要被导入的目标模块名(形式为字符串)。其他可选参数允许进一步定制化行为: - **name**: 要导入的模块的名字 (必需). - **globals**, **locals**: 控制命名解析环境,默认为空字典. - **fromlist**: 列表类型变量,指定要从里提取哪些子模块或属性; 如果不为空则尝试获取这些成员而不是整个模块本身. - **level**: 整数类型的值用于支持相对路径下的查找机制. 具体实现如下所示[^1]: ```python module = __import__('os') print(module.name) ``` 上述例子展示了如何通过传入 `'os'` 字符串完成操作系统接口库的引入操作,并打印其内部定义的一个名为 name 的属性。 对于更加复杂的需求来说,可以通过调整额外选项来自定义导入过程: ```python # 动态加载并访问特定功能 math_module = __import__('math', globals(), locals(), ['sqrt'], 0) result = math.sqrt(9) print(result) # 使用 fromlist 参数仅载入所需部分而非全部内容 numpy_random = __import__('numpy.random', globals(), locals(), [], 0).random array = numpy_random.randint(low=0, high=10, size=(3,)) print(array) ``` 值得注意的是,尽管 `__import__()` 提供了灵活性,但在大多数实际应用场合推荐优先选用标准的 `import` 关键字简化代码编写流程。除非确实存在必要理由,否则应避免直接调用这个底层工具以保持程序清晰易读性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值