Get the class that *defines* a method

Currently, the only way to get the name of the class that *defines* a method is to get chain of parent classes from inspect.getmro() and look into every class's dict until a given name is found. Knowing that dict contains not only methods, and knowing that it can be modified at run-time, this doesn't seem too reliable for me (unless Python itself does the same). At first I wanted to propose an enhancement to runtime skeleton of Python, which is 2D lookup tree for objects and containers that define them. But then I realized that it will may not reflect the model I need. For example, classes need to provide their parent classes, but in my model classes need to provide module name (or function name, or method name) in which they are defined. And while writing this I realized that *definition* scope may be different from *run-time* scope, and Python doesn't make it clear:
def lll(): ... class A(object): ... pass ... a=A() ... return a ... lll() <__main__.A object at 0x948252c> __main__.A Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name '__main__' is not defined
The A object is said to be in __main__ namespace, but it seems to be a run-time namespace local to function and it seems like Python loses this information. There is no information about the function that defined the class (owner, parent or .?.), and hence no info about container of the function, which makes it hard to assume the scope of variables for this class at run-time. So, the above is a generalization of a simple idea - store the "structure reference" of the class that *defines* a method inside this method. "structure reference" here is the address in the nested scopes formed by Python definitions. The specific action items for you here are: 1. is that stuff will be useful (for me it brings some much needed consistency into the chaos of run-time Python object space) 2. what is the best way to define/cache the reference to the class defining the method? 3. what is the best way to define/cache the reference to the scope defining the method? 4. what is the best way to organize storing of this static scope structure information at run-time? See method.im_class note at http://docs.python.org/2/library/inspect.html#types-and-members "Namespaces are one honking great idea -- let's do more of those!" (c) import this -- anatoly t.

Hi, 2013/6/23 anatoly techtonik <techtonik@gmail.com>
Currently, the only way to get the name of the class that *defines* a method is to get chain of parent classes from inspect.getmro() and look into every class's dict until a given name is found. Knowing that dict contains not only methods, and knowing that it can be modified at run-time, this doesn't seem too reliable for me (unless Python itself does the same).
Python 3.3 has __qualname__, which may be very useful in your case: http://docs.python.org/3/whatsnew/3.3.html#pep-3155-qualified-name-for-class... At first I wanted to propose an enhancement to runtime skeleton of Python,
which is 2D lookup tree for objects and containers that define them. But then I realized that it will may not reflect the model I need. For example, classes need to provide their parent classes, but in my model classes need to provide module name (or function name, or method name) in which they are defined.
And while writing this I realized that *definition* scope may be different from *run-time* scope, and Python doesn't make it clear:
def lll(): ... class A(object): ... pass ... a=A() ... return a ... lll() <__main__.A object at 0x948252c> __main__.A Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name '__main__' is not defined
The A object is said to be in __main__ namespace, but it seems to be a run-time namespace local to function and it seems like Python loses this information. There is no information about the function that defined the class (owner, parent or .?.), and hence no info about container of the function, which makes it hard to assume the scope of variables for this class at run-time.
So, the above is a generalization of a simple idea - store the "structure reference" of the class that *defines* a method inside this method. "structure reference" here is the address in the nested scopes formed by Python definitions.
The specific action items for you here are: 1. is that stuff will be useful (for me it brings some much needed consistency into the chaos of run-time Python object space) 2. what is the best way to define/cache the reference to the class defining the method? 3. what is the best way to define/cache the reference to the scope defining the method? 4. what is the best way to organize storing of this static scope structure information at run-time?
See method.im_class note at http://docs.python.org/2/library/inspect.html#types-and-members
"Namespaces are one honking great idea -- let's do more of those!" (c) import this -- anatoly t.
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- Amaury Forgeot d'Arc

On 2013-06-23 20:42, anatoly techtonik wrote:
Currently, the only way to get the name of the class that *defines* a method is to get chain of parent classes from inspect.getmro() and look into every class's dict until a given name is found. Knowing that dict contains not only methods, and knowing that it can be modified at run-time, this doesn't seem too reliable for me (unless Python itself does the same).
I think you can most robustly replicate what Python does by walking up the MRO and checking for the method by calling each class's __getattribute__() until it stops giving you the same method. The last class to give you the same method that type(the_instance) gives you is the class that defines the method.
At first I wanted to propose an enhancement to runtime skeleton of Python, which is 2D lookup tree for objects and containers that define them. But then I realized that it will may not reflect the model I need. For example, classes need to provide their parent classes, but in my model classes need to provide module name (or function name, or method name) in which they are defined.
And while writing this I realized that *definition* scope may be different from *run-time* scope, and Python doesn't make it clear:
def lll(): ... class A(object): ... pass ... a=A() ... return a ... lll() <__main__.A object at 0x948252c> __main__.A Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name '__main__' is not defined
The A object is said to be in __main__ namespace, but it seems to be a run-time namespace local to function and it seems like Python loses this information.
Classes defined in functions get assigned the name of the module that it is in, in this case `__main__` which is a real module recorded under that name in sys.modules. The example you have given doesn't show what you think it shows, just that the __main__ module (which the interpreter executes its code in) doesn't have a reference to itself. In general, modules don't include themselves in their namespace. You can get the class of an instance in the usual manner: type(). It is true that you cannot access that class *by name alone*. This is not fixable, even in principle.
There is no information about the function that defined the class (owner, parent or .?.), and hence no info about container of the function, which makes it hard to assume the scope of variables for this class at run-time.
If you had actually defined a method and actually used a variable from the local namespace (the only time where this information matters), the relevant information will be recorded in the `func_closure` attribute of the function object underneath the method. [~] |29> def foo(x): ...> class A(object): ...> def foo(self): ...> print x ...> return A() ...> [~] |30> a = foo(10) [~] |31> foo_method = type(a).foo [~] |32> foo_method <unbound method A.foo> [~] |33> foo_method.im foo_method.im_class foo_method.im_func foo_method.im_self [~] |33> foo_method.im_func <function __main__.foo> [~] |34> foo_method.im_func.func_closure (<cell at 0x109e16be8: int object at 0x1003100a0>,) [~] |35> foo_method.im_func.func_closure[0].cell_contents 10 You don't need to know about the function where the class definition is contained in to get this information. The function objects carry it around with them. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco

If you have the result of lll() and you want to get its type... Just call type on it: a = lll() A = type(a) It doesn't matter where the class was defined; this always works. If you're trying to access the type based on the information in an instance's repr, you're doing it wrong. The fact that it doesn't work in this case is irrelevant. It also doesn't work for any class that defines a __str__ or __repr__ or inherits from another class that does so. (It may not work even for a class deliberately designed to use the default object.__repr__ when run under different interpreters, because the particular format of that repr is just an implementation detail of CPython.) Let's give a very simple example:
class Foo(list): pass a = Foo() a []
You can't get the type from the repr. (Actually, your example is doubly irrelevant. The error you got is just because __main__ doesn't have a reference to itself; it has absolutely nothing to do with classes. But if you'd written sys.modules[__main__] instead, that would have shown what I think you wanted to show.) Sent from a random iPhone On Jun 23, 2013, at 12:42, anatoly techtonik <techtonik@gmail.com> wrote:
Currently, the only way to get the name of the class that *defines* a method is to get chain of parent classes from inspect.getmro() and look into every class's dict until a given name is found. Knowing that dict contains not only methods, and knowing that it can be modified at run-time, this doesn't seem too reliable for me (unless Python itself does the same).
At first I wanted to propose an enhancement to runtime skeleton of Python, which is 2D lookup tree for objects and containers that define them. But then I realized that it will may not reflect the model I need. For example, classes need to provide their parent classes, but in my model classes need to provide module name (or function name, or method name) in which they are defined.
And while writing this I realized that *definition* scope may be different from *run-time* scope, and Python doesn't make it clear:
def lll(): ... class A(object): ... pass ... a=A() ... return a ... lll() <__main__.A object at 0x948252c> __main__.A Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name '__main__' is not defined
The A object is said to be in __main__ namespace, but it seems to be a run-time namespace local to function and it seems like Python loses this information. There is no information about the function that defined the class (owner, parent or .?.), and hence no info about container of the function, which makes it hard to assume the scope of variables for this class at run-time.
So, the above is a generalization of a simple idea - store the "structure reference" of the class that *defines* a method inside this method. "structure reference" here is the address in the nested scopes formed by Python definitions.
The specific action items for you here are: 1. is that stuff will be useful (for me it brings some much needed consistency into the chaos of run-time Python object space) 2. what is the best way to define/cache the reference to the class defining the method? 3. what is the best way to define/cache the reference to the scope defining the method? 4. what is the best way to organize storing of this static scope structure information at run-time?
See method.im_class note at http://docs.python.org/2/library/inspect.html#types-and-members
"Namespaces are one honking great idea -- let's do more of those!" (c) import this -- anatoly t. _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
participants (4)
-
Amaury Forgeot d'Arc
-
anatoly techtonik
-
Andrew Barnert
-
Robert Kern