假设我按如下方式导入模块:
import os as OSMOD
然后想找到工作目录
OSMOD.getcwd()
OSMOD
现在是os
的替代品,使用os
将无效。这都是花花公子,对我有用。但是,我发现有些奇怪的东西。如果我像上面那样导入os
,然后获取所有导入模块的列表,那么会发生以下情况:
>>> import sys
>>> import os as OSMOD
>>> modList = sys.modules.keys()
>>> print "os" in modList
True
>>> print "OSMOD" in modList
False
这不是我的预期。根据文档modules.keys() only lists the imported modules
。对我来说,这意味着它应该列出OSMOD
。
为什么sys.modules.keys()
不包含OSMOD
而不是os
?
此外,是否有sys.modules.keys()
的等效列表,其中包含OSMOD
?
编辑:我想这里更大的问题是理由。如果Python要将os
作为模块,为什么要删除引用呢? (即,为什么os.getcwd()
和OSMOD.getcwd()
都不起作用?)
或者,更简单地说,为什么import os as OSMOD
的行为与import os
后跟OSMOD = os
的行为相同?
答案 0 :(得分:9)
因为模块的名称是os
。你做了import os
。 as OSMOD
只是告诉Python将该模块分配给模块命名空间中的名称OSMOD
。
sys.modules
是导入模块的缓存,用于防止模块多次导入。如果它将导入的模块存储在OSMOD
下,则另一个执行import os
的模块将再次导入该模块。
答案 1 :(得分:1)
sys.modules
包含导入模块的真实名称。但是,不包含使用as <name>
下导入的名称。
换句话说,当你这样做时:
import os as OSMOD
os
模块实际上是导入的。但是,它以OSMOD
的名称导入。
尽管如此,名称os
仍会添加到sys.modules
,因为这是导入模块的真实名称。 OSMOD
虽然未已添加,因为它不是模块。相反,它是导入的os
模块的备用名称。
答案 2 :(得分:1)
基本的import语句(no from子句)分两步执行:
- 找到一个模块,必要时加载并初始化
- 在本地命名空间中为import语句的范围定义一个或多个名称。
特别是,第二步意味着:
如果成功检索到请求的模块,它将以三种方式之一在本地命名空间中可用:
- 如果模块名称后跟as,则后面的名称将直接绑定到导入的模块。
这意味着您的模块可用的名称将显示在locals()
或globals()
中:
>>>import sys as X
>>> locals()['X']
<module 'sys' (built-in)>
>>>
答案 3 :(得分:1)
您似乎对模块对象以及对该对象的引用感到困惑。 sys.modules['os']
是对模块对象的一个引用,OSMOD
是另一个。
当您使用语句import os as OSMOD
时,Python确保将os
模块加载到内存中(使用sys.modules
字典作为缓存)然后创建对模块对象的引用你当前的命名空间因为您使用as OSMOD
Python看到您想要使用名称OSMOD
并将模块绑定到该名称。
如果您使用import os
,那么Python默认为与模块名称相同,因此它会将对象绑定到本地命名空间中的os
。
你绝不会受到限制。您仍然可以将同一个对象绑定到其他名称:
os = OSMOD
会给你另一个对同一模块对象的引用。
请记住,您的模块全局命名空间仅对模块是全局的;其他模块看不到相同的名称。因此,您希望控制在其中定义的名称。也许您希望将名称os
完全用于 else 。以下是合法的:
os = 'Ozzy Santana'
import os as OSMOD
我希望os
仍然绑定到字符串,而不是模块。
同时,我的Python项目中的另一个模块仍然可以使用import os
并让os
引用该模块;它不会在第一个模块中看到绑定到os
的字符串。
答案 4 :(得分:0)
您导入了os
。然后你把它放到名字OSMOD
。以下是发生的事情的简单说明:
import os
OSMOD = os
del os
导入的模块仍然是os
,而不是osmod
,因此它将是sys.modules.keys()
中列出的模块。
是的,type(OSMOD)
是一个模块,因为它绑定到模块对象。