Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: which types support weak references?

Code:

from weakref import WeakSet
se = WeakSet()
se.add(1)

Output:

TypeError: cannot create weak reference to 'int' object

Doc:

Several built-in types such as list and dict do not directly support weak references but can add support through subclassing:

...

Other built-in types such as tuple and int do not support weak references even when subclassed (This is an implementation detail and may be different across various Python implementations.).

This isn't expressive enough to explain:

  • Why some built-in types don't support weak references?

  • What are exactly those types that support weak references?


To add some thoughts:

For the above example you can wrap the int within a user-defined wrapper class, and that wrapper class supports weak references (Those who are familiar with Java will recall int and Integer):

from weakref import WeakSet
se = WeakSet()

class Integer:
    def __init__(self, n=0):
        self.n = n

i = 1
I = Integer(1)

se.add(i)   # fail
se.add(I)   # ok

I'm not sure why Python doesn't provide auto-wrapping for commonly used built-in types (int, str, etc.) but instead simply say they don't support weak references. It might be due to performance issues, but not being able to weakref these built-in types greatly reduced its usage.

like image 261
Cyker Avatar asked Aug 24 '18 20:08

Cyker


People also ask

What are weak references in Python?

A weak reference to an object is not enough to keep the object alive: when the only remaining references to a referent are weak references, garbage collection is free to destroy the referent and reuse its memory for something else.

What's a weak reference when would you want to use one?

A weak reference permits the garbage collector to collect the object while still allowing the application to access the object. A weak reference is valid only during the indeterminate amount of time until the object is collected when no strong references exist.

What are Weakref objects?

A WeakRef object contains a weak reference to an object, which is called its target or referent. A weak reference to an object is a reference that does not prevent the object from being reclaimed by the garbage collector. In contrast, a normal (or strong) reference keeps an object in memory.

What is a weak reference in programming?

In computer programming, a weak reference is a reference that does not protect the referenced object from collection by a garbage collector, unlike a strong reference.


1 Answers

First: this is all CPython-specific. Weakrefs work differently on different Python implementations.

Most built-in types don't support weak references because Python's weak reference mechanism adds some overhead to every object that supports weak references, and the Python dev team decided they didn't want most built-in types to pay that overhead. The simplest way this overhead manifests is that any object with weak reference support needs space for an extra pointer for weakref management, and most built-in objects don't reserve space for that pointer.

Attempting to compile a complete list of all types with weak reference support is about as fruitful as trying to compile a complete list of all humans with red hair. If you want to determine whether a type has weak reference support, you can check its __weakrefoffset__, which is nonzero for types with weak reference support:

>>> int.__weakrefoffset__
0
>>> type.__weakrefoffset__
368
>>> tuple.__weakrefoffset__
0
>>> class Foo(object):
...     pass
... 
>>> class Bar(tuple):
...     pass
... 
>>> Foo.__weakrefoffset__
24
>>> Bar.__weakrefoffset__
0

A type's __weakrefoffset__ is the offset in bytes from the start of an instance to the weakref pointer, or 0 if instances have no weakref pointer. It corresponds to the type struct's tp_weaklistoffset at C level. As of the time of this writing, __weakrefoffset__ is completely undocumented, but tp_weaklistoffset is documented, because people implementing extension types in C need to know about it.

like image 145
user2357112 supports Monica Avatar answered Oct 01 '22 03:10

user2357112 supports Monica