I've written a Python 3 metaclass containing a nested metaclass (with abc), like:
class A_M(object, metaclass=abc.ABCMeta):
class A_nested_M(object, metaclass=abc.ABCMeta):
def ... # some methods
Now, implementing like
class A(A_M):
class A_nested(A_nested_M):
def ...
doesn't work. So, did i miss something about usage of metaclasses or is this type of implementation with nested metaclasses not working at all?
First thing: Nesting class declarations is of near no use for anything in Python. Unless you are using the nested class hierarchy itself as a hard-coded namespace to keep attributes, you probably are doing the wrong thing already.
You did not tell what your (actual) problem is and what you are trying to achieve there, nor why you are using the ABCmeta metaclass. So it is hard to suggest any actually useful answers - but we can try clarifying some things:
First: you are not writting a metaclass, as you suggest in the text "I've written a Python 3 metaclass containing a nested metaclass..." - you are creating ordinary classes that have the ABCmeta as its metaclass. But you are not creating new metaclasses - You would if you were inheriting from type
or from ABCMeta
itself - them your new class would be used in the metaclass=
parameter of subsequent (ordinary) classes. That is not the case.
Now, second, everything that is defined inside the body of your outermost A_M
class will be only "visible" as attributes of A_M
itself. That is the source of your error - when you try to inherit from A_nested_M
you should actually write:
class A_M(object, metaclass=abc.ABCMeta):
class A_nested_M(object, metaclass=abc.ABCMeta):
def ... # some methods
class A(A_M):
class A_nested(A_M.A_nested_M):
def ...
See - A_M.A_nested_M
will make Python find the superclass for A_nested
: there is no reference in the local or global namespaces for A_nested_M
as it only exists as an attribute of A_M
outside the body of the class A_M...
statement.
That said, this is still useless. If you want to have instances of A_nested
referenced by instances of A
class, you have to create these instances inside A.__init__()
call - at which point it makes no difference if A_nested
is declared inside a class body or at the module level:
class A_M(object, metaclass=abc.ABCMeta):
pass
class A_nested_M(object, metaclass=abc.ABCMeta):
def ... # some methods
class A_nested(A_nested_M):
...
class A(A_M):
def __init__(self):
self.nested = A_nested()
Now, that can be of some use. You can also declare the classes actually nested, but the only way they can be useful is by creating instances of them anyway. And unlike nested functions, nested classes do not have access to attributes or variables declared on the "nesting" class namespace (but for referring to them by their qualified name. I.e. in your example, if the A
class would contain a b
classmethod, a method inside A_nested
that would call this method would have to call A.b()
, not b()
)