循环加载模块
假设你有两个文件,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:
>>> import a
1
没问题。也许令人惊讶,毕竟有一个循环加载感觉就像这里的问题。
其实在Python中只有循环加载的出现是没有问题的。如果模块已经加载,Python 不会愚蠢到重新加载它。然而,当每个模块都想访问彼此的函数或定义在另一个模块中的变量时,就会出现问题。
我们回到前面的例子,当我们加载a.py的时候,它加载b.py是没有问题的,因为加载b.py的时候,不需要从a.py访问任何东西,而在唯一的引用在 b.py 中是对 a.f() 的调用。但是这个调用是在函数g()中完成的,a.py或者b.py中都没有人调用g(),所以此刻的心情还是美好的。
但是当我们尝试加载 b.py 时会发生什么(之前没有加载 a.py):
>>> import b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "b.py", line 1, in <module>
import a
File "a.py", line 6, in <module>
print f()
File "a.py", line 4, in f
return b.x
AttributeError: 'module' object has no attribute 'x'
恭喜,出了点问题。这里的问题是在加载b.py的过程中,Python尝试加载a.py,而a.py中需要调用f(),函数f()需要访问b.x,但是此时b.x 尚未定义。这会导致 AttributeError 异常。
解决方案可以稍微改变。更改 b.py 以便它在 g() 中加载 a.py:
x = 1
def g():
import a
# 只有当g()被调用的时候才加载
print a.f()
这会儿当我们加载b.py的时候,一切安好:
>>> import b
>>> b.g()
1
# 第一次输出,因为模块a在最后调用了‘print f()’
1
# 第二次输出,这是我们调用g()
本文为原创文章,版权归知行编程网所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ 如何找到python列表?10/04
- ♥ 如何在pycharm中使用anaconda部署python环境09/08
- ♥ python算法有用吗?01/03
- ♥ 如何在 python 中计算 50 阶乘?01/14
- ♥ 如何用python写一个告白程序10/29
- ♥ 如何检查函数参数是否符合python条件?11/30
内容反馈