内容简介:昨晚在整理自己的python脚本的时候,想把其中一个脚本中的由于原脚本业务部分过长,这里把关键的几个部位抽出来做了个演示程序。执行上面的程序,在Linux终端上就会出现
昨晚在整理自己的 python 脚本的时候,想把其中一个脚本中的 print 函数全都改成 logging 包中的相关函数。改完后一运行却出现了 Exception AttributeError: 'NoneType' object has no attribute 的错误,网上搜了一下没找到相关答案。上午再想了想,原因应该是跟python对象的析构有关,具体分析过程如下:
1 示例程序
由于原脚本业务部分过长,这里把关键的几个部位抽出来做了个演示程序。
# -*- coding: UTF-8 -*-
# File: destrution_attribute_error_nonetype1.py
# Description: python自动析构时出现Exception AttributeError: 'NoneType' object has no attribute问题的示例程序
# (c) 2018.12.19 vfhky https://typecodes.com/python/destrution_attribute_error_nonetype1.html
import threading
import logging
# MYSQL 的简单封装
class CMySQL:
# 线程锁
_instance_lock = threading.Lock()
# 数据库连接对象
__db = None
# 游标对象
__cursor = None
def __init__(self, *args, **kwargs):
pass
def __new__(cls, *args, **kwargs):
pass
# 析构函数,释放对象时使用
def __del__(self):
# 关闭数据库连接
if self.__db:
self.__db.close()
# 自动析构时这里会出问题:'NoneType' object
logging.info("-------> close db.")
else:
# 自动析构时这里也会出问题:'NoneType' object
logging.warning("-------> db unconnected or had been closed.")
if __name__ == "__main__":
# 创建实例
db_obj = CMySQL()
# 输出到控制台
logging.basicConfig(level=logging.INFO,
format='[%(asctime)s][L:%(lineno)d][%(levelname)s][%(process)d] %(message)s',
datefmt='%d %b %Y %H:%M:%S')
logging.info("================================== END ==================================") |
2 执行后出现错误
执行上面的程序,在 Linux 终端上就会出现 Exception AttributeError: 'NoneType' object has no attribute 'warning'" in <bound method CMySQL.__del__ of <__main__.CMySQL instance at 0x7f4b3f9b7128>> 的错误。
如下图所示:
3 分析问题
其实是不了解python的析构过程导致的:当main函数结束后(输出图中的 END 字样),意味着进程即将退出,那么会自动调用对象的析构函数进行析构,这点Python和C++是一样的。
由于 logging 模块中的类对象(包括成员变量、成员函数等)已经被析构了,所以当执行 CMySQL 对象的析构函数 __del__ 中的 logging.warning 函数时会出现 "'NoneType' object has no attribute 'warning' 的错误。
4 解决问题
解决方法很简单,只要增加一个封装 MySQL 链接关闭的函数 close 就行了,当main函数结果调用即可。下面的代码是针对这个问题的改进版本。
# -*- coding: UTF-8 -*-
# File: destrution_attribute_error_nonetype1_1.py
# Description: 修正Exception AttributeError: 'NoneType' object has no attribute问题的示例程序
# (c) 2018.12.19 vfhky https://typecodes.com/python/destrution_attribute_error_nonetype1.html
import threading
import logging
# MYSQL 的简单封装
class CMySQL:
# 线程锁
_instance_lock = threading.Lock()
# 数据库连接对象
__db = None
# 游标对象
__cursor = None
def __init__(self, *args, **kwargs):
pass
def __new__(cls, *args, **kwargs):
pass
# 关闭数据库连接
def close(self):
if self.__db:
self.__db.close()
self.__db = None
self.__cursor = None
logging.info("-------> close db.")
else:
logging.warning("-------> db unconnected or had been closed.")
# 析构函数,释放对象时使用
def __del__(self):
# 关闭数据库连接
if self.__db:
self.__db.close()
self.__db = None
self.__cursor = None
# logging.info("-------> close db.")
else:
pass
#logging.warning("-------> db unconnected or had been closed.")
if __name__ == "__main__":
#
db_obj = CMySQL()
# 输出到控制台
logging.basicConfig(level=logging.INFO,
format='[%(asctime)s][L:%(lineno)d][%(levelname)s][%(process)d] %(message)s',
datefmt='%d %b %Y %H:%M:%S')
logging.info("================================== END ==================================")
# 关闭数据库连接
db_obj.close() |
运行效果如下图所示:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- acme.sh 续期问题(路径问题)
- 缓存的一些问题和一些加密算法【缓存问题】
- 如何把设计问题转化为数学问题(方法论)
- 推荐系统中的冷启动问题和探索利用问题
- GraphQL 教程(六)—— N+1问题和缓存等问题
- Golang 并发问题(四)之单核上的并发问题
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Machine Learning in Action
Peter Harrington / Manning Publications / 2012-4-19 / GBP 29.99
It's been said that data is the new "dirt"—the raw material from which and on which you build the structures of the modern world. And like dirt, data can seem like a limitless, undifferentiated mass. ......一起来看看 《Machine Learning in Action》 这本书的介绍吧!