- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
在 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
是一个包,并且 mod
或 mod2
是该包中的模块 尚未导入,因为它们在第三种和第五种情况下。 __import__()
函数需要知道 mod
和 mod2
是 import
语句想要拥有的名称可访问,以便它可以查看它们是否是模块并尝试导入它们。所以调用更接近:
tmp = __import__('pkg', fromlist=['mod', 'mod2'])
mod = tmp.mod
mod2 = tmp.mod2
这会导致 __import__()
尝试加载 pkg.mod
和 pkg.mod2
以及 pkg
(但如果 mod
或 mod2
不存在,则在 __import__()
调用中不是错误;产生错误留给import
语句。)但这仍然不是第四个和第五个示例的正确方法,因为如果调用是这样的:
tmp = __import__('pkg.mod', fromlist=['submod'])
submod = tmp.submod
然后 tmp
最终会像以前一样成为 pkg
,而不是您想要获取 的
属性来自。实现可能已经决定这样做,所以 pkg.mod
模块submodimport
语句做了额外的工作,在 .
上拆分包名称,就像 __import__()
函数一样确实并遍历名称,但这意味着重复一些工作。因此,相反,实现使 __import__()
返回 right-most 模块而不是 left-most 一个 if and only如果 fromlist 已通过且不为空。
(import pkg as p
和 from pkg import mod as m
语法不会改变这个故事的任何内容,除了分配给哪些本地名称 - __import__()
函数在使用 as
时没有什么不同,它都保留在 import
语句实现中。)
关于python - 为什么 Python 的 __import__ 需要 fromlist?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2724260/
基本上我很好奇代码是否像: let myCollection = Data.SomeCollection.fromList [1, 2, foo] 实际上是在执行它在运行时的样子,并创建一个链表作为创
作为我理解单例旅程的一部分,我试图弥合编译时安全性和将运行时值提升到依赖类型安全性之间的差距。 我认为“运行时”值的一个最小示例是一个接受无界列表并将其转换为大小索引向量的函数。以下骨架提供了长度索引
作为我理解单例旅程的一部分,我试图弥合编译时安全性和将运行时值提升到依赖类型安全性之间的差距。 我认为“运行时”值的一个最小示例是一个接受无界列表并将其转换为大小索引向量的函数。以下骨架提供了长度索引
我正在尝试摸索进入依赖类型。基于下面 windowl 函数的逻辑,我想返回一个向量列表,其长度取决于提供的 size。 window : (n : Nat) -> List a -> List (Ve
通常,当将 Python 和 C 代码粘合在一起时,需要将 Python 列表转换为连续的内存,例如一个 array.array。这个转换步骤成为瓶颈也很常见,所以我发现自己用 Cython 做一些愚
在 Python 中,如果你想以编程方式导入模块,你可以这样做: module = __import__('module_name') 如果你想导入一个子模块,你会认为这很简单: module = _
我是一名优秀的程序员,十分优秀!