metaclass可以使用attrs查看、修改子类的属性
其中是class的属性,不是(创建之后的,self.)对象的
可以从输出carry在最后看到,Test定义之后马上生成,而不是等到有语句。
self.d是不存在的,__init__也被看成属性(attrs),然后也被pop了。
所以在pop完之后,元类的派生类只存在attrs指定的属性。
其中,带有self并且是第一个参数的属于对象的属性,否则是class的。
代码和例子:
class TestMetaclass(type):
def __new__(cls, name, bases, attrs):
mappings = dict()
for k, v in attrs.items():
print(k, v)
mappings[k] = v
for k in mappings.keys():
attrs.pop(k)
attrs['return_str'] = lambda self, p: '%s' % p
attrs['c'] = 23
return type.__new__(cls, name, bases, attrs)
class Test(object, metaclass = TestMetaclass):
a = 'c'
b = 1
def __init__(self, d = 4):
self.d = d
def f(self, p):
print(p)
print('carry')
t = Test()
print(t.return_str('fds'))
print(Test.c)
print(t.d)
结果:
wujing@ubuntu:~/Desktop$ python3 test.py
__module__ __main__
__qualname__ Test
a c
b 1
__init__ <function Test.__init__ at 0x7fd83882aae8>
f <function Test.f at 0x7fd83882ab70>
carry
fds
23
Traceback (most recent call last):
File "test.py", line 26, in <module>
print(t.d)
AttributeError: 'Test' object has no attribute 'd'