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

一、问题背景

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

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

转载于:https://my.oschina.net/shong/blog/887654

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值