为什么80%的码农都做不了架构师?>>>
一、问题背景
使用了两套环境:开发环境和测试环境。开发环境上运行没有问题,测试环境运行就报错。
AttributeError:'module' object has no attribute 'getListOfTable'
二、问题分析
仔细看代码:
1、模块之间是有引用的,但都已经import了,没问题!
2、模块mcommon.py中已经有方法 getListOfTable
def getListOfTable(table_name):
既然都这样了,我拍着连接六块腹肌的胸脯保证,代码没问题!
三、解决办法
狗日的,环境部署问题!测试环境上面是直接copy相关的.py文件,不包括.pyc文件。
直接删除mcommon.pyc文件,重启程序,OK...
四、附注
- pyc文件是python编译后的字节码(bytecode)文件。
- 第一次运行py文件,python编译器会自动生成与py文件对应的pyc字节码文件,就像java中.java文件对应.class文件。
- 下次调用时,程序直接调用pyc,而不调用py文件,直到该py文件改变了。
- python解释器会检查pyc文件的生成时间,对比py文件的修改时间。如果py更新,那么就生成新的pyc。
reference: Python脚本报错AttributeError
五、补记
对自己的代码太自信了,有的时候会打嘴!哈哈哈哈......前面拍胸脯的那位,其实代码还是有问题滴。
删除pyc文件之后,测试环境跑了一会儿,还是报错,一样的错误提示。删除pyc竟然也不管用了。
怎么办?用uncompyle2反编译pyc看看,到底是什么鬼。
噢噢噢噢....我日,里面空荡荡的!
问题的真正原因是这样的:模块之间的方法存在互相调用的情况,即circular import。例如:
文件a.py
#encoding:utf-8
#a.py
import b
def print_a():
print("here is print_a")
b.print_b()
print_a()
文件b.py
#encoding:utf-8
#b.py
import a
def print_b():
print("here is print_b")
a.print_a()
print_b()
运行任何一个py文件都会报错,如运行 a.py的报错
AttributeError: 'module' object has no attribute 'print_b'
程序执行过程分析如下:
>>> 执行a.py及import b
>>> 执行b.py及import a
>>> 执行a.py及import b
因为之前执行过了,所以b.py已经在sys.modules里面。
python不会重新执行b.py,而只是把sys.modules里面的b.py返回给你。
当执行到a.py的print_a()的时候,程序仍未执行b.py里面的print_b(),所以会报错说找不到b.py中的print_b()。提示"AttributeError: 'module' object has no attribute 'print_b'"。
解决办法:
(1)在实际项目中,我是直接解除这种循环引用,如a.py中可以引用b.py,但b.py不引用a.py。问题解决。
(2)如果不能避免,必须要这么引用,怎么办?可以延迟引用。例如在b.py中,不要一开始就是import a,而是在print_b()方法中import a。当然,这样的话执行上面的两个例子会死循环。实际项目中,肯定不会有哪个混蛋会这么写。
reference: http://stackoverflow.com/questions/744373/circular-or-cyclic-imports-in-python