How to make a class inside another inherit a variable instantiated from the latter in python?

1

See the following python script:

class a:
        def __init__(self,n):
                self.n=n

        class b:
                def __init__(self):
                        ## o que botar aqui para receber a variável self.n ##
                def show(self):
                        return self.n
inst=a(3).b()
print(inst.show())

Class "b" is within class "a". Class "a" has an argument (besides self) and class "b" has none. I would like to know how to make class "b" inherit the variable "self.n" from class "a" so that it can be used in the "show" method. The goal is for this script to show the number 3.

    
asked by anonymous 24.01.2017 / 20:37

2 answers

3

In Python you must explicitly create access

You must access the inner class through a function in the outer class.

Try this:

class externa(object):
    def __init__(self, n):
        self.n = n        

    def getInterna(self):
        return self.interna(self)

    class interna(object):
        def __init__ (self, pai):
            self.pai = pai

        def show(self):
            return self.pai.n

inst = externa(3).getInterna()

print(inst.show())
    
24.01.2017 / 21:03
2

Not understanding your problem is a complicated question to answer. The question does not make much sense.

But come on - why do you want to declare one class internal to the other? The class declaration itself does not create objects of this class - the only difference is that in order to instantiate the class b , in the example you give, it is necessary to type a.b() - in this case Python searches inside the class % with% of the a self 'attribute that is put into methods.

That is, in:

class a:
    def b(self):
        ...

When you call b verifica que é "chamável" - como não é uma função ordinária, essa chamada não ganha automaticamente o parâmetro , Python itself places the b attribute there.

In your example, the self class is instantiated normally and will not know anything about the a.b class - much less about specific instances of it.

The way to pass this reference is to instantiate the class in a method - which can be used as a "factory" of objects a - this is practically the same as in the other answer:

class a:
    def __init__(self):
         ...
    def b_factory(self):
         return self.__class__.b(self)

    class b:
         def __init__(self, instancia_pai):
               self.instancia_pai = instancia_pai
               print(self.instanca_pai.n)

You noted in the comment that "so much does the class b be within a.b " EXACTLY - because for any practical effect, it really does. If a needs to have instances of a attached to each instance, you can do this on your own b - And the Python syntax allows you to declare classes one within the other, and use these classes as __init__ for class attributes - but at the time you want to start instantiating those classes, and have references to instances - (you want the Namespaces attribute of an instance of self.n ), you must pass these instances as parameters to the methods.

The answer you want

Although it does not make sense what you want to do, Python has a dynamic attribute mechanism called a , which can be used to do whatever you need, but in the "right" way. Internally it is the mechanism that Python uses to append the descriptors parameter to methods, and is more commonly used in user code with the decorator self of Python.

It is this: every time Python retrieves an attribute from a class, it checks to see if that attribute exists first in the class (not first in the instance) - if so, it checks to see if the attribute has special method% with%. If you have, instead of continuing the search, Python calls this method property by passing the instance and class where the attribute was searched as parameters.

Except that things are different. The __get__ method must be of the class of the recovered attribute. If the attribute itself is the class, it does not work. That is: to use __get__ the classes have in their body instances of classes that have method __get__ and not the classes themselves. You can even make the declaration nested but, to work, you have to have an instance of the nested class, not the class itself in the body of descriptors :

In short, your code can be written like this:

class a:
    def __init__(self,n):
        self.n=n

    class b:
        def __init__(self):
            ...

        def show(self):
            return self.instance.n

        def __get__(self, instance, owner):
             self.instance = instance
  c = b()

And with this code you can do: __get__ But not a (and yes, notice that it does not make the slightest difference that the statement of a(5).c.show() is inside a(5).b.show() - and yes, if I had called the instance b of a it would be in the same - only that you would no longer have access to the c class, only a single instance created from it).

I'm not sure what you want to do with nested classes - but look at the documentation on b , and you'll probably see that they can do what you're trying to do with nested classes.

The official Python documentation on b is extremely concise and it's all here: link

And in general, the descriptors class that comes ready, descriptors , already does everything that's needed: link

    
25.01.2017 / 04:42