python报错AttributeError:'module' object has no attribute 'xxxxx'

原创
2017/04/26 16:06
阅读数 2.1W

一、问题背景

使用了两套环境:开发环境和测试环境。开发环境上运行没有问题,测试环境运行就报错。

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

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部