pythonlibrary-design

Use outer class instance as self in inner class?


I'm writing a wrapper for the GMAIL API. In this wrapper, I am trying to include subattributes in the "main class" so it more closely follows the below:

picture

Previously, I was use methods such as:

class Foo:
    def __init__(self, ...):
        # add some attributes

    def get_method(self, ...):
        return some_stuff

This allows me to do foo.get_method(...). To follow the GMAIL API, I try to do:

class Foo:
     def __init__(self, ...):
         # add some attributes

     @property
     def method(self):
         class _Method:
             @staticmethod
             def get(self, ...):
                 return some_stuff
         return _Method()

Which allows me to do foo.method.get(...). The above has some problems, it redefines the class every time, and I have to add @staticmethod above every method as part of it. I do realise that I could create the class at the outer class level, and set a hidden variable for each which then .method returns or creates, but this seems like too much workaround.

tldr: Is it possible to make the instance passed to the inner class as self be the instance of the outer class (I do not wish to have to pass the attributes of the outer class to each inner class).


Solution

  • Instead of sharing the self parameter between classes, you are probably better off just passing the things you need to the constructor of the class you instantiate.

    class Messages:
        def __init__(self, name):
            self.name = name
    
        def method(self, other_arg):
            return self.name + other_arg
    
    class Test:
        name = "hi"
    
        def __init__(self):
            self.messages = Messages(name=self.name)
    

    If you need to pass a lot of information to the constructor and it starts becoming unwieldy, you can do something like split the shared code into a third class, and then pass that between the Test and Messages classes as a single object.

    In Python there are all sorts of clever things that you can do with metaclasses and magic methods, but in 99% of cases just refactoring things into different classes and functions will get you more readable and maintainable code.