我编写了一个包含嵌套元类(带有abc)的Python 3元类,如:
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_nested_M):
def ...
不起作用。那么,我是否错过了关于元类使用的一些内容,或者这种类型的实现与嵌套的元类根本不起作用?
答案 0 :(得分:3)
第一件事: 嵌套类声明几乎没有用于Python中的任何内容。除非您使用嵌套类层次结构本身作为硬编码命名空间来保存属性,否则您可能已经做错了。
你没有说出你的(实际)问题是什么以及你想要在那里实现什么,也没有告诉你为什么要使用ABCmeta元类。因此很难提出任何实际有用的答案 - 但我们可以尝试澄清一些事情:
首先:你没有像你在文本中所建议的那样写一个元类;我已经编写了一个包含嵌套元类的Python 3元类......" - 您正在创建 将ABCmeta作为其元类的普通类。但是你没有创建新的元类 - 如果你继承自type
或者ABCMeta
本身 - 那么你的新类将被用在后续(普通)类的metaclass=
参数中。事实并非如此。
现在,第二,在最外面的A_M
类的主体内定义的所有内容将只有#34;可见"作为A_M
本身的属性。这是您的错误的来源 - 当您尝试从A_nested_M
继承时,您应该写下:
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 ...
请参阅 - A_M.A_nested_M
将使Python找到A_nested
的超类:A_nested_M
的本地或全局命名空间中没有引用,因为它仅作为{{1}的属性存在在A_M
语句的正文之外。
那就是说,这仍然没用。如果您希望class A_M...
类的实例引用{em>实例 A_nested
,则必须在A
调用内创建这些实例 - 此时它不会如果在类体内或模块级别声明A.__init__()
,则会产生差异:
A_nested
现在,这可能有些用处。您也可以声明实际嵌套的类,但它们唯一有用的方法是创建它们的实例。与嵌套函数不同,嵌套类无法访问在"嵌套"上声明的属性或变量。 class namespace(但是用于通过它们的限定名称引用它们。即在您的示例中,如果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()
类包含A
类方法,b
内部将调用此方法的方法将必须致电A_nested
,而不是A.b()
)
答案 1 :(得分:0)
你应该像这样实现你的类:
class A(A_M):
class A_nested(A_M.A_nested_M):
def ...
因为A_nested_M
是一个内部类,所以您应该像访问任何类属性一样访问它,即A_M.A_nested_M
。请参阅this link。