Python2.7进程退出时全局变量的__del__异常分析

本文分析了Python2.7服务在退出时出现的全局变量__del__异常,原因是模块卸载顺序的不确定性导致的。通过复现问题,发现在进程退出时,Python模块的卸载顺序可能导致全局对象引用的类在模块已被卸载的情况下依然被调用,从而引发异常。解决方案包括在sys.exitfunc中手动释放全局变量或改变方法调用形式。
摘要由CSDN通过智能技术生成

0x01 背景

工作中有同事发现有一个Python2.7编写的服务在退出时,看到有如下的异常信息。这里的Python2.7,即指CPython2.7,下面统称为Python。

Exception TypeError: 'super() argument 1 must be type, not None' in <bound method XXX.__del__ of <XXX object at 0x7f0144ac3cd0>> ignored

这个错误发生在__del__方法调用时。熟悉Python的同学会知道,__del__方法的调用发生在对象实例被销毁时。这个错误也没有太大影响,但本着认真学习的态度,想找出来,为什么会出现这个异常。

通过异常信息,可以看出是在调用__del__时,对象的类型变为了None。这就非常有趣了。好好的,一个对象类型怎么变成了None了呢?因为我们知道None这个对象是没有__del__方法的。可以在交互shell中通过dir(None)确认。进一步原因是因为None这个对象,在Python的实现里,只有一个。

$ python
dPython 2.7.15+ (default, Nov 27 2018, 23:36:35)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> dir(None)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__'
, '__subclasshook__']

注意到异常的对象是一个全局对象,思路就定在全局对象在进程退出时是如何回收的。进一步通过研究Python的源码,本文在解答上述异常的原因外,还将解答以下问题。

  1. Python中dict中的元素是无序的,具体是什么样子的?同样的参数生成的dict实例,每次的无序序列都是不同的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值