Mikhail Gerasimov
Mikhail Gerasimov

Reputation: 39536

Access outer class object from inner class in Python 3

I read similar questions on SO, but couldn't find answer.

This question is not about accessing instance of outer class or it's method, but about accessing outer class object that should be normal task. As soon as we have __qualname__ that contains information about outer class's name, there is no reason why not to be able dynamically access to outer class object.

This example do job:

class Outer:
    class Inner:
        @classmethod
        def parent_class(cls):
            outer_name = cls.__qualname__.split('.')[-2]
            outer_cls = globals()[outer_name]
            print(outer_cls)


Outer.Inner.parent_class()  # <class '__main__.Outer'>

But it wouldn't work in parent_class function placed in another module:

# some.py
class Some:
    @classmethod
    def parent_class(cls):
        outer_name = cls.__qualname__.split('.')[-2]
        outer_cls = globals()[outer_name]
        print(outer_cls)

# main.py
from some import Some


class Outer:
    class Inner(Some):
        pass

Outer.Inner.parent_class()  # KeyError: 'Outer'

I think it can be solved with Outer's class decorator that appends it's class object to all nested classes, but is there any "clean" way just to get outer class object?

Upvotes: 0

Views: 258

Answers (1)

Mikhail Gerasimov
Mikhail Gerasimov

Reputation: 39536

Looks like this solution works in every case:

import sys


class Outer:
    class Inner:
        @classmethod
        def parent_class(cls):
            outer_name = cls.__qualname__.split('.')[-2]
            outer_module = sys.modules[cls.__module__]
            outer_cls = vars(outer_module)[outer_name]
            print(outer_cls)


Outer.Inner.parent_class()  # <class '__main__.Outer'>

Upvotes: 1

Related Questions