3

We can easily determine an object's mro, by accessing its __mro__ attribute.

In my case I have a really complex hierarchy that I'm trying to untangle to avoid the current mro hell we are undergoing.

I have a very long mro chain like this one:

(<class 'CompanyUserViewSet'>, <class 'CompanyGenericViewSet'>, <class 'CompanyDispatchMixin'>, <class 'CompanyCorsLiteMixin'>, <class 'CorsLiteMixin'>, <class 'ErrorHandlingMixin'>, ..., <type 'object'>) 

This is shortened for the sake of the question, but in this case it sums up to 19 classes.

I currently have a problem: I need to know from which one of these classes python is resolving the as_view method.

I know I can check these in order, but I fail to see what I'm doing wrong, since the as_view that is getting called is not the correct one.

The call to the method is pretty simple, we have a CompanyUserViewSet that Rest Framework is using to build the urls for a router:

view = viewset.as_view(mapping, **route.initkwargs) 

How can I determine, given an object and one of its attributes (or methods) from what class is python resolving it?

6
  • how is it being called? Commented Oct 15, 2015 at 17:16
  • @PadraicCunningham on an instance of the first type in the list Commented Oct 15, 2015 at 17:18
  • Are their metaclasses involved? Are parent implementations called via super? There are a few variables that can change the default MRO. Commented Oct 15, 2015 at 17:20
  • I was probably unclear, I mean are you using super() in a class or Class.method or simply inheriting? Commented Oct 15, 2015 at 17:20
  • @PadraicCunningham well, no metaclass issues for sure, but there are 19 classes, some used super, others didn't. qualname solved the issue in a second :) Commented Oct 15, 2015 at 17:30

1 Answer 1

4

To get where a method is defined use, method.__func__.__qualname__. That requires Python >= 3.3. In older pythons you can use the qualname package.

See the example below:

class A: def f1(): return 'f1A' def f2(): return 'f2A' class B(A): def f2(): return 'f2B' a = A() b = B() print(a.f1.__func__.__qualname__) print(a.f2.__func__.__qualname__) print(b.f1.__func__.__qualname__) print(b.f2.__func__.__qualname__) 

which produces the output:

A.f1 A.f2 A.f1 B.f2 

If you are using the qualname package:

import qualname print qualname.qualname(a.f1) print qualname.qualname(a.f2) print qualname.qualname(b.f1) print qualname.qualname(b.f2) 
Sign up to request clarification or add additional context in comments.

1 Comment

This. This worked like a charm, don't get the downvote

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.