Python import机制 (十七)

1.import
Python 中所有加载到内存的模块都放在 sys.modules 。当 import 一个模块时首先会在这个字典中查找是否已经加载了此模块,如果加载了则只是将模块的名字加入到正在调用 import 的模块的 Local 名字空间中。如果没有加载则从 sys.path 目录中按照模块名称查找模块文件,模块可以是py、pyc、pyd,找到后将模块载入内存,并加到 sys.modules 中,并将名称导入到当前的 Local 名字空间。


2.同一模块多次import,但只会导入一次
因为每次import的时候会先查看当前的名字空间是否已经导入了该模块,没有则加入该模块到名字空间

a.py

class A:pass
print "import B"
b.py
for i in range(10):
    from a import A
运行b.py
输出:
import B

3.相互引用
a.py

from b import B
class A:pass
b.py
from a import A
class B:pass
当运行a.py的时候抛出以下错误:
Traceback (most recent call last):
  File "E:\work\test\test_import\a.py", line 9, in <module>
    from b import B
  File "E:\work\test\test_import\b.py", line 9, in <module>
    from a import A
  File "E:\work\test\test_import\a.py", line 9, in <module>
    from b import B
ImportError: cannot import name B

从异常中可以找到产生异常的原因:
(1)from b import B:开始在sys.modules中查找是否已经加载了此模块,没有加载-->创建新的module(这时候该module为空)
(2)执行b.py,加载对象(会将b.py从上到下加载一遍)。
(3)当加载到from a import A时,“又”会转到a.py,执行a.py,加载对象
(4)在执行a.py,加载对象时,当加载到from b import B时
(5)sys.modules中查找已经加载了此模块,所以会在sys.modules中取"B"对象
(6)此时"B"对象并没有加载到sys.modules中,所以会抛出:cannot import name B

可以使用以下方法来避免这种异常(最好不要使用相互import):
(1)将a.py中的"from b import B"修改为"import b",因为"import b"不会立即执行b.py所以不会产生异常,但是当调用b.py下的模块时,一样会执行b.py加载模块,同样会产生异常
(2)将b.py中的"from a import A"放在"class B:pass"后面,因为在a.py再次"from b import B"的时候B已经在sys.modules中了

注意:import 只能导入模块(文件或module),不能导入模块中的对象(类、函数、变量等),但是可以通过"from xxx import xx"来导入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值