【问题标题】:Python del on classesPython del 类
【发布时间】:2011-08-02 06:01:27
【问题描述】:

假设我们在 python 中有一个类:

class A(object):
    def __del__(self):
        print "Del!"

__del__ 在删除/垃圾收集任何 A 实例时被调用。

是否可以为班级做同样的事情?我想在类本身被垃圾收集时调用一些方法,我假设这是在脚本退出时完成的。

提前感谢您的任何指点!


编辑:正如我所料,每个人都试图让我远离使用这种技术(我自己可能会发表这样的评论:)),尽管问题仍然存在:是可能吗?

我想要以下内容:我有一个需要清理的带有静态成员的类。

class A(object):
    class Meta(type):
        def __new__(mcs, name, bases, attrs):
            attrs['conn'] = sqlite3.connect( DB_FILE )
            return type.__new__(mcs, name, bases, attrs)

    __metaclass__ = Meta

我希望在程序关闭之前调用A.conn.close() - 即当我知道不会再创建A 的实例时。我知道我可以用atexit 做到这一点,但这看起来很丑。

【问题讨论】:

  • 使用__del__ 已经很可疑了。它可以使对象无法进行 GC(在存在循环的情况下,GC 不知道必须以什么顺序调用它们,因为可能存在一些依赖项)并且由于它是不确定的,因此最好将清理放入上下文中经理。你认为你为什么需要这个?
  • 您可以创建一个工厂类,该类具有 __call__ 方法来创建所需类的新实例和 __del__ 方法来满足您的需求
  • 不管怎样,我想不出任何有用的东西。
  • 永远不要依赖垃圾收集来处理一组特定的行为。运行时没有义务收集任何东西,即使在程序终止时也是如此。如果您需要清理,请使用上下文管理器。
  • 在垃圾收集环境中,析构函数是一件坏事。躲开它。或者,更确切地说,问一个关于你正在解决的问题的问题,而不是小技术问题。也许这会带来真正的答案。

标签: python class del


【解决方案1】:

问题在于类包含对自身的循环引用 - 所以当它们被删除时,它们不容易被收集 - 因此不会调用元类的 __del__ 方法。

我可以使用 Pypy 的 Python 实现来触发它,但不能使用 cpython - 2.6 或 3.2。甚至为了触发它,我不得不手动调用垃圾收集器—— 众所周知,程序退出时的 Python 环境充满了不一致性,在存在足够的类内部信息以允许 sae 关闭的情况下调用 __del__ 方法的可能性非常小。

这是我的 Pypy 会话,在那里我触发了对班级的调用'__del__

 ~]$ pypy                                                                                       
Python 2.5.2 (78826, Nov 29 2010, 00:18:05)                                                                       
[PyPy 1.4.0] on linux2                                                                                            
Type "help", "copyright", "credits" or "license" for more information.                                            
And now for something completely different: ``sorry, I'll teach the cactus how                                    
to swim later''                                                                                                   
>>>> import gc
>>>> class Meta(type):         
....    def __del__(cls):                          
....       print ("Arghh!!")                                              
....                                                                      
>>>> class A(object):                                                                     
....   __metaclass__ = Meta                                                                                     
....                                                                                                                                                                                                                
>>>> del A                                                                                                        
>>>> gc.collect()                                                                                                 
Arghh!!                                                                                                           
0                                                                                                                 
>>>>

【讨论】:

  • And now for something completely different: "sorry, I'll teach the cactus how to swim later" 这让我很开心。谢谢。
猜你喜欢
  • 2013-02-04
  • 2019-04-18
  • 2018-05-05
  • 2017-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-10
  • 2019-04-28
相关资源
最近更新 更多