Вы неправильно поняли, как работает del
. Он не удаляет предметы. Он удаляет имена.
Например, у вас есть
>>> x = [1, 2, 3]
>>> y = x
>>> z = x
Все три имени, x
, y
, z
относятся к одному и тому же объекту списка. Теперь удалите x
:
>>> del x
>>> x
NameError: name 'x' is not defined
Для y
и z
после этого не имело бы смысла поднимать NameError
. Особенно представьте, если бы y
и z
были ссылками в другой функции или модуле. Если del x
заставит другие ссылки исчезнуть, это приведет к очень неожиданному и нежелательному поведению.
Итак, при нормальных обстоятельствах вы не можете делать то, что хотите. Ваш текущий метод просто удаляет имя self
в локальном пространстве имен самого метода. Он не может легко изменить глобальное пространство имен.
При этом вы можете написать функцию, которая удаляет имя из глобального пространства имен. Например:
class MyClass:
def myFunc(self, name):
del globals()[name]
myInst = MyClass()
myInst.myFunc('myInst')
Теперь, если вы попытаетесь получить доступ к myInst
, имя исчезнет в скрипте. Это плохая идея, и, скорее всего, она все равно не удалит объект. Если у вас есть другая ссылка на myInst
, например, в list
, dict
или прямое присвоение другому имени, эта ссылка будет сохраняться, как и сам объект.
Намного лучший подход, как предлагается в комментариях, это пометить экземпляр как непригодный для использования. Например, вы можете сделать что-то вроде
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!')
Существуют более надежные способы реализации флага, чтобы сделать его менее доступным для обычного пользователя, но они в основном следуют тому же шаблону.