2

I have a collection of user-created objects in my Python application.

If the user deletes one of these objects, for the purposes of error checking only, I'd like to flag it as having been deleted, such that any attempts to use that object in future result in an error.

I considered some options:

  • del: this deletes the reference and leaves any dangling references intact.
  • __dict__.clear() this gives a confusing AttributeError when the object is accessed, and removes all the information which may be helpful in tracking the object down

I also considered overriding __getattribute__ however, changing this seems to be ineffective.

class MyClass:
    def __init__( self ):
        self.a = 1
        self.b = 2
        self.c = 3

m = MyClass()

print( m.a )
print( m.b )
print( m.c )


def fn_deleted( self, attribute ):
    raise ValueError( "This object should have been deleted :(" )


m.__getattribute__ = fn_deleted

print( m.a ) # <-- NO ERROR

I feel there should be a simple way of checking for dangling references. Any ideas?

c z
  • 7,726
  • 3
  • 46
  • 59
  • 1
    How about registering your objects (using metaclass) to a dict, that holds references to all instances. When an instance is deleted, it unregister, leaving the dict pointing to None instead of the object. – Chen A. Jun 11 '18 at 16:57
  • 2
    Usually, you'd just remove it from the collection. – user2357112 Jun 11 '18 at 17:05

1 Answers1

2
class MyClass(object):
    def __init__( self ):
        self.a = 1
        self.b = 2
        self.c = 3
        self.__deleted__ = dict()

    def __delattr__(self, item):
        value = self.__getattribute__(item)
        self.__deleted__[item] = value
        # optional actually delete attribute..
        super().__delattr__(item)

    def __getattribute__(self, item):
        if item == '__deleted__':
            return super().__getattribute__(item)
        elif item in self.__deleted__:
            print('item has been deleted, prev value: {}'.format(self.__deleted__[item]))
        else:
            return super().__getattribute__(item)

m = MyClass()
print( m.a )
del m.a
print( m.a )

---------------------------
1
item has been deleted, prev value: 1
None
Attack68
  • 4,437
  • 1
  • 20
  • 40