Python 中的自定义析构函数
Custom destructor in Python
假设我有两个 类:
class Container():
def __init__(self, name):
self.name = name
class Data():
def __init__(self):
self._containers = []
def add_container(self,name):
self._containers.append(name)
setattr(self, name, Container(name))
现在说
myData = Data()
myData.add_container('contA')
现在,如果我 del myData.contA
它当然不会从 myData._containers
中删除 name
。
那么我如何在 Container
中编写析构函数以便它删除属性但同时从 _containers
列表中删除名称?
您想重载 __delattr__
特殊方法:https://docs.python.org/3/reference/datamodel.html#object.delattr
class Data:
[...]
def __delattr__(self, key):
super().__delattr__(name)
#find and remove the Container from _containers
您似乎习惯了一种具有确定性对象销毁和执行该销毁的专用方法的语言。 Python 这样不行。 Python 没有析构函数,即使它有析构函数,也不能保证 del myData.contA
会使 Container 对象符合销毁条件,更不用说实际销毁它了。
可能最简单的方法是定义一个 remove_container
平行于你的 add_container
:
def remove_container(self, name):
self._containers.remove(name)
delattr(self, name)
如果您确实希望此操作的语法为 del myData.contA
,则通过在 Data
:
上实现 __delattr__
来挂钩属性删除
def __delattr__(self, name):
self._containers.remove(name)
super().__delattr__(name)
假设我有两个 类:
class Container():
def __init__(self, name):
self.name = name
class Data():
def __init__(self):
self._containers = []
def add_container(self,name):
self._containers.append(name)
setattr(self, name, Container(name))
现在说
myData = Data()
myData.add_container('contA')
现在,如果我 del myData.contA
它当然不会从 myData._containers
中删除 name
。
那么我如何在 Container
中编写析构函数以便它删除属性但同时从 _containers
列表中删除名称?
您想重载 __delattr__
特殊方法:https://docs.python.org/3/reference/datamodel.html#object.delattr
class Data:
[...]
def __delattr__(self, key):
super().__delattr__(name)
#find and remove the Container from _containers
您似乎习惯了一种具有确定性对象销毁和执行该销毁的专用方法的语言。 Python 这样不行。 Python 没有析构函数,即使它有析构函数,也不能保证 del myData.contA
会使 Container 对象符合销毁条件,更不用说实际销毁它了。
可能最简单的方法是定义一个 remove_container
平行于你的 add_container
:
def remove_container(self, name):
self._containers.remove(name)
delattr(self, name)
如果您确实希望此操作的语法为 del myData.contA
,则通过在 Data
:
__delattr__
来挂钩属性删除
def __delattr__(self, name):
self._containers.remove(name)
super().__delattr__(name)