Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Weak reference auf bound method

0 views
Skip to first unread message

Ole Streicher

unread,
Oct 2, 2009, 4:50:23 AM10/2/09
to
Hallo,

im Zusammenhang mit dem Async-Problem ist mir noch etwas aufgefallen --
"Bound methods" verhalten sich in weakrefs komisch:

class MyClass(object):
def myfunc(self):
pass

o = MyClass()
print o.myfunc
>>>> <bound method MyClass.myfunc of <__main__.MyClass object at 0xc675d0>>

import weakref
r = weakref.ref(o.myfunc)
print r()
>>>> None

Nanu? Das Objekt "o" gibt es doch noch, und damit auch die passende
bound method "o.myfunc". Die weakref behauptet aber, sie gäbe es nicht
mehr. Wie kann ich erreichen, dass die Referenz erhalten bleibt, solange
"o" lebt?

Viele Grüße

Ole

Stefan Behnel

unread,
Oct 2, 2009, 7:38:40 AM10/2/09
to
Ole Streicher schrieb:

> "Bound methods" verhalten sich in weakrefs komisch:
>
> class MyClass(object):
> def myfunc(self):
> pass
>
> o = MyClass()
> print o.myfunc
> >>>> <bound method MyClass.myfunc of <__main__.MyClass object at 0xc675d0>>
>
> import weakref
> r = weakref.ref(o.myfunc)
> print r()
> >>>> None

Na ja, das passiert eben, wenn mensch eine Funktion aufruft, die keinen
Rᅵckgabewert hat.

Stefan

Ole Streicher

unread,
Oct 2, 2009, 7:50:14 AM10/2/09
to
Hallo Stefan,

Stefan Behnel <stef...@behnel.de> writes:
>> import weakref
>> r = weakref.ref(o.myfunc)
>> print r()
>> >>>> None
> Na ja, das passiert eben, wenn mensch eine Funktion aufruft, die keinen

> Rückgabewert hat.

| class weakref.ref(object[, callback])
| Return a weak reference to object. The original object can be
| retrieved by calling the reference object if the referent is still
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| alive; if the referent is no longer alive, calling the reference
| object will cause None to be returned.

r ist das reference object. Das originale Objekt (die Funktion) erhält
man, wenn man das Referenzobejkt aufruft:

r()

Den Rückgabewert der Funktion würde man erhalten, wenn man dieses Objekt
aufruft:

r()()

Das kann man testen:

import weakref

class MyClass(object):
def myfunc(self):
pass

o = MyClass()
f = o.myfunc # ********************* #

r = weakref.ref(o.myfunc)
print r()

liefert tatsächlich eine Referenz auf die Funktion zurück. Wenn man die
durch Sterne markierte Zeile weglässt, dann kommt "None" zurück.

Ich bin zwar blutiger Python-Anfänger, aber soviel habe ich davon dann
doch schon verstanden :-)

Viele Grüße

Ole


Stefan Behnel

unread,
Oct 2, 2009, 7:56:25 AM10/2/09
to
Ole Streicher schrieb:

> Stefan Behnel writes:
>>> import weakref
>>> r = weakref.ref(o.myfunc)
>>> print r()
>>>>>>> None
>> Na ja, das passiert eben, wenn mensch eine Funktion aufruft, die keinen
>> Rᅵckgabewert hat.

>
> | class weakref.ref(object[, callback])
> | Return a weak reference to object. The original object can be
> | retrieved by calling the reference object if the referent is still
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> | alive; if the referent is no longer alive, calling the reference
> | object will cause None to be returned.
> [...]

> import weakref
>
> class MyClass(object):
> def myfunc(self):
> pass
>
> o = MyClass()
> f = o.myfunc # ********************* #
> r = weakref.ref(o.myfunc)
> print r()
>
> liefert tatsᅵchlich eine Referenz auf die Funktion zurᅵck. Wenn man die
> durch Sterne markierte Zeile weglᅵsst, dann kommt "None" zurᅵck.

Ah, ok, dann hilft das hier vielleicht weiter:

Python 2.6.2 (r262:71600, Apr 17 2009, 11:29:30)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class Test:
... def x(self): pass
...
>>> Test.x
<unbound method Test.x>
>>> id(Test.x)
3084677684L
>>> id(Test.x)
3084717828L
>>> x1 = Test.x
>>> x2 = Test.x
>>> x1 is x2
False

>>> t = Test()
>>> t.x
<bound method Test.x of <__main__.Test instance at 0xb7dee3cc>>
>>> x1 = t.x
>>> x2 = t.x
>>> x1 is x2
False

Stefan

Ole Streicher

unread,
Oct 2, 2009, 8:05:05 AM10/2/09
to
Hallo Stefan

Stefan Behnel <stef...@behnel.de> writes:
> <bound method Test.x of <__main__.Test instance at 0xb7dee3cc>>
> >>> x1 = t.x
> >>> x2 = t.x
> >>> x1 is x2
> False

Dank der Diskussion in der englischsprachigen Newsgroup weiß ich
inzwischen, woran es liegt -- habe aber leider noch keine Lösung für das
Problem.

Viele Grüße

Ole

0 new messages