Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deleting main object by deleting reference

I am working with large nested dictionaries, and am trying to delete nested subdictionaries. I am wondering why the following behavior occurs.

When I set a reference to dictionary d (called ref), then I change ref and print d, it shows an updated version of d with the third element added.

input:
d={"a":1,"b":2}
ref=d
ref["c"]=3
print(d)

output:
{'a': 1, 'b': 2, 'c': 3}

Given this behavior, I was expecting to be able to delete the dictionary by delete

input:
d={"a":1,"b":2}
ref=d
del ref
print(d)

output:
{'a': 1, 'b': 2}

I am wondering if there is a way to delete the original object when I delete the reference (meaning that the output of the second program would be an error because d was deleted.

like image 208
user1763510 Avatar asked Aug 14 '18 00:08

user1763510


People also ask

How to delete the object in JavaScript?

The only way to fully remove the properties of an object in JavaScript is by using delete operator. If the property which you're trying to delete doesn't exist, delete won't have any effect and can return true.

Which keyword is used for deleting properties on objects?

delete keyword is used to delete properties of an object in javaScript.

How do you delete an object in Python?

To delete an object in Python, we use the 'del' keyword. A when we try to refer to a deleted object, it raises NameError.

What is the purpose of the delete operator?

The delete operator removes a given property from an object. On successful deletion, it will return true , else false will be returned.


1 Answers

del doesn't actually handle any de-allocation of memory, it merely unbinds a value from a name, and then decrements the reference count of that object by one. There is no way to systematically unbind all names from an object given a single reference.

An object is not garbage collected until some point after the reference count drops to 0. You can see an object's reference count by using the sys.getrefcount method (which is typically one higher than it actually is because of the temporary reference within the method itself).

We can demonstrate del in practice using this method and the __del__ method (which is called only when the reference count for the object is decremented to 0):

>>> # print something when refcount == 0 and object is about to be collected
>>> class Deleted:
...     def __del__(self):
...         print("actually deleted")
...
>>> a = Deleted()
>>> # just a
>>> sys.getrefcount(a) - 1
1
>>> b = a
>>> # a and b
>>> sys.getrefcount(a) - 1
2
>>> del a
>>> # now it's just b
>>> sys.getrefcount(b) - 1
1
>>> del b
actually deleted

If you're curious to read more about how all of this works internally, check out the C API documentation on the internal calls for reference counting, and check out the gc module, which is the high level python interface for introspecting the garbage collection sub-system.

Given your specific problem, since you are working with dictionaries which are mutable types, you could just clear the dictionary:

>>> a = {"a": 1}
>>> b = a
>>> # will clear the dict that both a and b are referencing
>>> b.clear()
>>> a
{}

Alternatively you can use the equivalent range syntax to clear the dictionary del a[:].

like image 191
Matthew Story Avatar answered Oct 21 '22 11:10

Matthew Story