Пользовательский деструктор в Python - PullRequest
0 голосов
/ 18 сентября 2018

Допустим, у меня есть два класса:

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, это, конечно, не удалит name изmyData._containers.

Так как мне написать деструктор в Container, чтобы он удалял атрибут, а также удалял имя из списка _containers?

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Вы, кажется, привыкли к языку с детерминированным уничтожением объектов и специальными методами для его уничтожения.Python не работает таким образом.В Python нет деструкторов, и даже если бы он имел деструкторы, нет гарантии, что del myData.contA сделает объект-контейнер пригодным для уничтожения, не говоря уже о его уничтожении.

Вероятно, самый простой способ - это просто определитьremove_container распараллеливание вашего add_container:

def remove_container(self, name):
    self._containers.remove(name)
    delattr(self, name)

Если вы действительно хотите, чтобы синтаксис этой операции был del myData.contA, то подключитесь к удалению атрибута, реализовав __delattr__ для Data:

def __delattr__(self, name):
    self._containers.remove(name)
    super().__delattr__(name)
0 голосов
/ 18 сентября 2018

Вы хотите перегрузить специальный метод __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
...