fc.
fc.

Reputation: 11

Deleting attributes when deleting instance

class A: def __get(self): return self._x

 def __set(self, y):
  self._x = y

 def __delete_x(self):
  print('DELETING')
  del self._x

 x = property(__get,__set,__delete_x)

b = A()

# Here, when b is deleted, i'd like b.x to be deleted, i.e __delete_x()
# called (and for immediate consequence, "DELETING" printed)
del b

Upvotes: 1

Views: 186

Answers (3)

fc.
fc.

Reputation: 11

An ugly way to do it would be :

def __del__(self):
    for x in dir(self.__class__):
        if type(getattr(self.__class__, x)) == property:
            getattr(self.__class__, x).fdel(self)

Upvotes: 0

mithrandi
mithrandi

Reputation: 1650

The semantics of the del statement don't really lend themselves to what you want here. del b simple removes the reference to the A object you just instantiated from the local scope frame / dictionary; this does not directly cause any operation to be performed on the object itself. If that was the last reference to the object, then the reference count dropping to zero, or the garbage collector collecting a cycle, may cause the object to be deallocated. You could observe this by adding a __del__ method to the object, or by adding a weakref callback that performs the desired actions.

Neither of the latter two solutions seems like a great idea, though; __del__ methods prevent the garbage collector from collecting any cycles involving the object; and while weakrefs do not suffer from this problem, in either case you may be running in a strange environment (such as during program shutdown), which may make it difficult to get done what you want to accomplish.

If you can expand on your exact use case, it may be that there is an entirely different approach to accomplishing your desired end goal, but it is difficult to speculate based on such a general and limited example.

Upvotes: 2

Alex Martelli
Alex Martelli

Reputation: 881715

To control what happens when an instance of class A goes away (whether by being deleted or garbage collected), you can implement special method __del__(self) in A. If you want to have your code involved when a specific attribute of that instance goes away, you can either wrap that attribute with a wrapper class which has __del__, or, probably better in most cases, use the weakref module (however, not all types are subject to being target of weak references, so you may also need some wrapping for this case).

Avoiding __del__ is generally preferable, if you possibly can, because it can interfere with garbage collection and thereby cause "memory leaks" if and when you have circular references.

Upvotes: 1

Related Questions