user32531323
user32531323

Reputation: 13

How to get the id of the underlying function bound to an object by a method-wrapper?

Consider the following case:

>>> "a".capitalize.__call__
<method-wrapper '__call__' of builtin_function_or_method object at 0x1022e70d8>
>>> "a".capitalize.__call__.__call__
<method-wrapper '__call__' of method-wrapper object at 0x1022e2b70>
>>> id("a".capitalize.__call__)
4331547448
>>> id("a".capitalize.__call__.__call__)
4331547504
>>> id("a".capitalize.__call__) == id("a".capitalize.__call__.__call__)
False

How can I establish at runtime that the __call__ refers to the same base symbol in both cases ?

Edit: It is possible that expecting something like this to exist for __call__ in the first place is unreasonable because __call__ might not have a base symbol that is not bound to any object - in which case what is the best way to detect that other than keeping a list of special names (how can such a list be built authoritatively ?) ?

Upvotes: 1

Views: 146

Answers (1)

Julien Palard
Julien Palard

Reputation: 11526

Won't work for builtin_function_or_method as they have no __func__.

If you're only working with your classes you can compare __func__:

>>> class Foo:
...     def bar(self):
...         pass
... 
>>> 
>>> a = Foo()
>>> b = Foo()
>>> a.bar.__func__
<function Foo.bar at 0x7f6f103e5ae8>
>>> a.bar.__func__ is b.bar.__func__
True

But I'd say it's better to do it the other way around: instead of trying to get the function from the instance, get up to the type first:

type(a).bar is type(a).bar

Which should work even for bltns:

>>> type("").capitalize is type("a").capitalize
True

And for hierarchies:

>>> class A:
...     def foo(self):...
... 
>>> class B(A):...
... 
>>> a = A()
>>> b = B()
>>> type(a).foo is type(b).foo
True

Upvotes: 2

Related Questions