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