十个Python程序员易犯的错误(七)

转自:http://www.weidianyuedu.com/

常见错误7:模块之间出现循环依赖(circular dependencies)
假设你有两个文件,分别是a.py和b.py,二者相互引用,如下所示:

a.py文件中的代码:

import b
def f():
return b.x
print f()
b.py文件中的代码:

import a
x = 1
def g():
print a.f()
首先,我们尝试导入a.py模块:

代码运行正常。也许这出乎了你的意料。毕竟,我们这里存在循环引用这个问题,想必应该是会出现问题的,难道不是吗?

答案是,仅仅存在循环引用的情况本身并不会导致问题。如果一个模块已经被引用了,Python可以做到不再次进行引用。但是如果每个模块试图访问其他模块定义的函数或变量的时机不对,那么你就很可能陷入困境。

那么回到我们的示例,当我们导入a.py模块时,它在引用b.py模块时是不会出现问题的,因为b.py模块在被引用时,并不需要访问在a.py模块中定义的任何变量或函数。b.py模块中对a模块唯一的引用,就是调用了a模块的foo()函数。但是那个函数调用发生在g()函数当中,而a.py或b.py模块中都没有调用g()函数。所以,不会出现问题。

但是,如果我们试着导入b.py模块呢(即之前没有引用a.py模块的前提下):

import b
Traceback (most recent call last):
File “”, line 1, in
File “b.py”, line 1, in
import a
File “a.py”, line 6, in
print f()
File “a.py”, line 4, in f
return b.x
AttributeError: ‘module’ object has no attribute ‘x’
糟糕。情况不太妙!这里的问题是,在导入b.py的过程中,它试图引用a.py模块,而a.py模块接着又要调用foo()函数,这个foo()函数接着又试图去访问b.x变量。但是这个时候,b.x变量还没有被定义,所以才出现了AttributeError异常。

解决这个问题有一种非常简单的方法,就是简单地修改下b.py模块,在g()函数内部才引用a.py:

x = 1
def g():
import a # This will be evaluated only when g() is called
print a.f()
现在我们再导入b.py模块的话,就不会出现任何问题了:

import b
b.g()
1 # Printed a first time since module ‘a’ calls ‘print f()’ at the end
1 # Printed a second time, this one is our call to ‘g’

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值