Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: dereferencing weakproxy

Is there any way to get the original object from a weakproxy pointed to it? eg is there the inverse to weakref.proxy()?

A simplified example(python2.7):
import weakref

class C(object):
    def __init__(self, other):
        self.other = weakref.proxy(other)

class Other(object):
    pass

others = [Other() for i in xrange(3)]

my_list = [C(others[i % len(others)]) for i in xrange(10)]

I need to get the list of unique other members from my_list. The way I prefer for such tasks is to use set:

unique_others = {x.other for x in my_list}

Unfortunately this throws TypeError: unhashable type: 'weakproxy'

I have managed to solve the specific problem in an imperative way(slow and dirty):
unique_others = []
for x in my_list:
    if x.other in unique_others:
        continue
    unique_others.append(x.other)

but the general problem noted in the caption is still active. What if I have only my_list under control and others are burried in some lib and someone may delete them at any time, and I want to prevent the deletion by collecting nonweak refs in a list?

Or I may want to get the repr() of the object itself, not <weakproxy at xx to Other at xx> I guess there should be something like weakref.unproxy I'm not aware about.
like image 301
robyschek Avatar asked Apr 20 '12 12:04

robyschek


People also ask

What is __ Weakref __ in Python?

__weakref__ is just an opaque object that references all the weak references to the current object. In actual fact it's an instance of weakref (or sometimes weakproxy ) which is both a weak reference to the object and part of a doubly linked list to all weak references for that object.

How do you use weak references in Python?

To create weak references in python, we need to use the weakref module. The weakref is not sufficient to keep the object alive. A basic use of the weak reference is to implement cache or mappings for a large object. Not all objects can be weakly referenced.

What is Weakref proxy?

weakref.proxy(object[,callback])Returns a proxy to the object that uses a weak reference. The returned object has type ProxyType or CallableProxyType, depending on if the object is callable. These objects are not hashable.


1 Answers

I know that this is an old question, but I've been bitten by it (so, there's no real 'unproxy' in the standard library) and wanted to share my solution...

The way I solved it to get the real instance was just creating a property which returned it (although I suggest using weakref.ref instead of a weakref.proxy as code should really check if it's still alive before accessing it instead of having to remember to catch an exception whenever any attribute is accessed).

Anyways, if you still must use a proxy, the code to get the real instance is:

import weakref

class MyClass(object):

    @property
    def real_self(self):
        return self

instance = MyClass()
proxied = weakref.proxy(instance)
assert proxied.real_self is instance
like image 164
Fabio Zadrozny Avatar answered Sep 20 '22 18:09

Fabio Zadrozny