1

I would like to delete an instance of my object after executing a function so that no python script can access this instance anymore.

Here is my code:

class MyClass():
    def myFunc(self):
       ...
       del self

myClass = MyClass()
myClass.myFunc()
print(myClass) # Supposed to raise an error because myClass is supposed to be deleted but that's not the case

What's going wrong?

3
  • You cannot delete objects in Python, Python is a memory-managed language. del deletes names from namespaces not objects. You simply deleted the local variable self, which ceases to exist after the function executes anyway so it is totally pointless Commented Aug 6, 2020 at 18:31
  • 1
    All that you will do with the del statement is delete the reference in the local variable self - which was about to happen anyway when the method returns. Other references to the same object are unaffected. Commented Aug 6, 2020 at 18:32
  • You can't actually delete the instance - but you can certainly put it in a state where nothing further can be done with it (similar to how a closed file object still exists, but produces an "operation attempted on closed file" exception for most methods). This could be done by adding a flag attribute, that all of your methods check before doing anything, or perhaps simply by deleting critical attributes such that any method on the object would fail. Commented Aug 6, 2020 at 18:39

2 Answers 2

2

You misunderstood how del works. It does not remove objects. It removes names.

For example, say you have

>>> x = [1, 2, 3]
>>> y = x
>>> z = x

All three names, x, y, z refer to the same list object. Now delete x:

>>> del x
>>> x
NameError: name 'x' is not defined

It would make no sense for y and z to raise a NameError after this. Imagine especially if y and z were references in a different function or module. Having del x make other references disappear would lead to some very unexpected and undesirable behaviors.

So under normal circumstances, you can't quite do what you want to do. Your current method is just removing the name self in the local namespace of the method itself. It can not easily modify the global namespace.

That being said, you can write a function that removes a name from the global namespace. For example:

class MyClass:
    def myFunc(self, name):
        del globals()[name]

myInst = MyClass()
myInst.myFunc('myInst')

Now, if you attempt to access myInst, the name will be gone in the script. This is a bad idea, and likely won't delete the object at all anyway. If you had another reference to myInst, e.g. in a list, dict or direct assignment to another name, that reference would persist, and so would the object itself.

A much better approach, as suggested in the comments, is to mark the instance as unusable. For example, you can do something like

class MyClass:
    def __init__(self):
        self.useable = True

    def my_func(self):
        self._check_useable()

        # do your thing...

        self.useable = False

    def other_func(self, *args):
        self._check_useable()
        # Do stuff to args ...

    def _check_useable(self):
        if not self.useable:
            raise ValueError('Class is not useable!')

There are more robust ways of implementing the flag to make it less accessible to the casual user, but they basically follow the same pattern.

Sign up to request clarification or add additional context in comments.

Comments

1

Since you can't delete objects in python and only delete the appearance of variables in the namespace. I would recommend just raising an error once the function is called once. Since you want an error to occur after its run.

class MyClass():
   def myFunc(self):
      ...
      counter += 1
      del self

counter = 0
# Check if the function has been run once and then raise exception
if counter > 0:
    raise exception("Instance cannot be used")

myClass = MyClass()
myClass.myFunc()
print(myClass)

I hope this still does what you anticipate but the del function only deletes the appearance of variable in the namespace and not allowing you to reference it anymore (But its not being deleted).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.