【问题标题】:Method that gets called on module deletion in Python在 Python 中删除模块时调用的方法
【发布时间】:2010-10-30 23:15:21
【问题描述】:

有没有一种方法可以添加到我的模块中,在销毁类时会被调用?

我们有一个简单的类,它只有静态成员函数,卸载模块时需要清理数据库连接。

希望没有实例的模块或类有一个__del__ 方法吗?

【问题讨论】:

  • “模块删除”是什么意思?你认为这会在什么时候发生?
  • 我们有一个简单的类,它只有静态成员函数,卸载模块时需要清理数据库连接。希望对于没有实例的模块或类有一个 del 方法?
  • @Dan:请用新信息更新问题;不要评论你自己的问题。另外,卸载模块的用例是什么?你为什么要这样做?

标签: python destructor shutdown


【解决方案1】:

什么时候销毁哪个类?我虽然你说的是模块?

您的模块一直存在,直到解释器停止。你可以使用“atexit”模块添加一些东西来运行:

import atexit
atexit.register(myfunction)

编辑:根据您的 cmets。

既然你不希望它作为析构函数,我上面的回答是正确的。只需定义另一个函数(或静态方法,如果您愿意)并将其注册到 atexit:

def close_database():
    proceed_to_close()

import atexit
atexit.register(close_database)

现在简要说明一下您的定义。

你说这个类没有任何实例。那么为什么要把它变成一个类呢?为什么不在模块级别定义函数呢?模块是一流的对象,只缓存和导入一次...

示例,而不是定义database.py

class DataBase(object):
    @staticmethod
    def execute_some_query(query):
        code_here()
        some_code()
    @staticmethod
    def close_database():
        proceed_to_close()
import atexit ; atexit.register(DataBase.close_database)

并使用:

from database import DataBase
DataBase.execute_some_query(query)

您可以在 database.py 上执行此操作:

def execute_some_query(query):
    code_here()
    some_code()

def close_database():
    proceed_to_close()
import atexit ; atexit.register(close_database)

并像这样使用它:

import database
database.execute_some_query(query)

或者更好:使用sqlalchemy 并避免创建自己的数据库接口的所有这些麻烦。

【讨论】:

    【解决方案2】:

    您要查找的类析构方法是__del__。在 __del__ 中调用它的时间以及如何处理异常和子类化存在一些细微差别,因此请务必阅读 official docs

    关于术语的快速说明:在 python 中,module 是您的代码所在的文件……本质上是一个命名空间。一个模块可以包含许多类、变量和函数。 __del__ 方法位于类上,而不是模块上。

    【讨论】:

      【解决方案3】:

      使用del方法:

      class Foo:
      
          def __init__(self):
              print "constructor called."
      
          def __del__(self):
              print "destructor called."
      

      【讨论】:

      • init 不是构造函数。如果你使用 del,gc 可能不会收集对象,所以一般情况下,如果可以的话,最好避免使用 del
      • 从技术上讲,类的调用是构造函数;它调用 newinit 是一个初始化器。一堆非常细微的区别。
      • @S.Lott 不,不是。一个类是它的元类的实例,所以如果你实例化一个类,你就调用元类的实例。所以你可以说Class.__metaclass__.__call__ 是构造函数。但是通常你认为Class.__new__ 是构造函数。
      【解决方案4】:

      使用 bpython 测试...

      >>> import atexit
      >>> class Test( object ):
      ...     @staticmethod
      ...     def __cleanup__():
      ...         print("cleanup")
      ...     atexit.register(Test.__cleanup__)
      ... 
      Traceback (most recent call last):
        File "<input>", line 1, in <module>
        File "<input>", line 6, in Test
      NameError: name 'Test' is not defined
      

      【讨论】:

      • 您已经缩进了 register 调用,使其成为类的一部分,但该类还不存在。将您所做的与接受的答案中的各种示例进行比较。
      • 啊,好的。我没有意识到此时该课程不存在。
      猜你喜欢
      • 2011-01-30
      • 2015-01-06
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 2015-09-15
      • 2014-11-30
      • 2021-02-23
      • 1970-01-01
      相关资源
      最近更新 更多