20

Supose you have something like:

x = "something"
b = x
l = [b]

How can you delete the object only having one reference, say x?

del x won't do the trick; the object is still reachable from b, for example.

smci
  • 32,567
  • 20
  • 113
  • 146
Juanjo Conti
  • 28,823
  • 42
  • 111
  • 133
  • 3
    where is this `a` you are talking about? – John La Rooy Jun 10 '10 at 10:02
  • 3
    why would you want to do this? – SilentGhost Jun 10 '10 at 11:37
  • What do you propose b and l point at after the string is deleted? Or do you really want to delete x,b, and l? – phkahler Jun 10 '10 at 12:00
  • I'd like to point the to something like "deleted" for example. – Juanjo Conti Jun 10 '10 at 12:27
  • @JuanjoConti Deleted objects get garbage-collected whenever the GC algorithm decides to. You have no reason to be referencing deleted objects after deleting them, so why do you care? What specific programming issue are you trying to fix? Are you merely trying to make them cosmetically appear deleted in a debugger view or something (in which case you could have their `__del__` method overwrite with zeros, or `0xdeadbeef`)? Or are you debugging an actual race condition where they are in fact somehow getting referenced after being deleted but before GC'd (possibly a threading issue)? Or why? – smci Feb 27 '19 at 02:33
  • 1
    "the object only having one reference, say x?" "the object is still reachable from b" This is a contradiction. `x` isn't "the object"; `x` is **a name for** the object. (In your terms, a reference to it.) **So is `b`**. So it has two names, and `del` on one of them still leaves it with a name. – Karl Knechtel Aug 12 '22 at 03:28

3 Answers3

19

No no no. Python has a garbage collector that has very strong territory issues - it won't mess with you creating objects, you don't mess with it deleting objects.

Simply put, it can't be done, and for a good reason.

If, for instance, your need comes from cases of, say, caching algorithms that keep references, but should not prevent data from being garbage collected once no one is using it, you might want to take a look at weakref.

abyx
  • 69,862
  • 18
  • 95
  • 117
  • 1
    the porpuse is to esure that the object wont be used again. – Juanjo Conti Jun 10 '10 at 12:29
  • 1
    @Juanjo then do this in the proper programmatic way. Your objects should allow you to 'close' the subject, or whatever it is you're trying to do. There's no magic involved. Just like a file has to be closed once, no matter how many functions have read/written to it – abyx Jun 10 '10 at 12:32
  • 1
    @Juanjo: Deleting an element doesn't ensure it won't be used again. In fact, if it's used again, your program will crash. Write your code wisely and don't use objects you don't want to be using. – Xavier Ho Jun 10 '10 at 12:47
  • 1
    Yeah well, also relax, no kids will die if you delete a reference – Omar Gonzalez Jul 09 '18 at 01:34
12

The only solution I see right now is that you should make sure that you are holding the only reference to x, everyone else must not get x itself but a weak reference pointing to x. Weak references are implemented in the weakref module and you can use it this way:

>>> import weakref
>>> class TestClass(object):
...     def bark(self):
...         print "woof!"
...     def __del__(self):
...         print "destructor called"
...
>>> x = TestClass()
>>> b = weakref.proxy(x)
>>> b
<weakproxy at 0x7fa44dbddd08; to TestClass at 0x7fa44f9093d0>
>>> b.bark()
woof!
>>> del x
destructor called
>>> b.bark()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ReferenceError: weakly-referenced object no longer exists

However, note that not all classes can be weak-referenced. In particular, most built-in types cannot. Some built-in types can be weak-referenced if you subclass them (like dict), but others cannot (like int).

Tamás
  • 47,239
  • 12
  • 105
  • 124
  • 1
    `str` cannot be weak-referenced, not even if you subclass it. Weak-referencing strings would open up a huge can of worms; for instance, the Python interpreter may choose to "intern" a string object and keep it around in memory even if there are no references to it in the hope that it might be useful later. Usually the interpreter does so with small strings and integers, but you can also choose to intern a string with the `intern` builtin (at least in Python 2.x). – Tamás Jun 11 '10 at 13:04
4

You don't. That's the entire point. Imagine if l is in a library outside of your control. It has every right to expect that the collection elements don't dissappear.

Also, imagine if it was otherwise. You'd have questions here on SO "How do I prevent others from deleting my objects?". As a language designer, you can't satisfy both demands.

MSalters
  • 173,980
  • 10
  • 155
  • 350