Last active
April 20, 2017 15:36
-
-
Save maxnordlund/f89fe5bc5878e699cb6fbc4b4ebb1407 to your computer and use it in GitHub Desktop.
Get the defining class for a unbound method in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def get_class(method): | |
""" | |
Get the class that the defined the provided method. | |
In Python 3 the concept of unbound method is removed and raw method | |
references are just plain functions. But it is sometimes useful to get the | |
class that defined that method. Unfortunately that turns out to be hard. | |
But there is a sure fire way of doing it, because Python exposes the | |
variables that a method can access, which by definition includes the | |
surronding class, so just go through that and find the class. | |
Of course it's not quite that simple. First off to find the class we check | |
if the value has an attribute that is named the same as the method, and is | |
a reference to the same. But we also have to check the qualifed name to | |
avoid subclasses shadowing the origin class. | |
>>> class Foo: | |
... def bar(self): | |
... pass | |
... | |
>>> get_class(Foo.bar) is Foo | |
True | |
>>> class Foo: | |
... def bar(self): | |
... pass | |
... | |
>>> class Bar(Foo): | |
... pass # don't override bar, it's still Foo's version | |
... | |
>>> get_class(Foo.bar) is Foo | |
True | |
>>> get_class(Bar.bar) is Foo | |
True | |
""" | |
for value in method.__globals__.copy().values(): | |
if hasattr(value, method.__name__) and \ | |
getattr(value, method.__name__) is method and \ | |
f"{value.__qualname__}.{method.__name__}" == method.__qualname__: | |
return value |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment