# -*- coding:utf-8 -*-
class MyMeta(type):
def __new__(cls, name, bases, attr):
# attr['add'] = lambda self, x, y : x+y
# attr['age'] = 0
attr['addr'] = 'gz'
return type.__new__(cls, name, bases, attr)
def __init__(cls, name, bases, attr):
super(MyMeta, cls).__init__(name, bases, attr)
attr['age'] = 0
cls.gender = 'male'
print(cls)
print(name)
print(bases)
print(attr)
class MyClass(object, metaclass=MyMeta):
def __init__(self):
# self.age = 1
self.name = 'hh'
m = MyClass()
print(m.name)
print(m.gender)
print(m.addr)
print(m.age)
# output:
<class '__main__.MyClass'>
MyClass
(<class 'object'>,)
{'__module__': '__main__', '__qualname__': 'MyClass', '__init__': <function MyClass.__init__ at 0x1100cb268>, 'addr': 'gz', 'age': <function MyMeta.__init__.<locals>.<lambda> at 0x1100cb2f0>}
hh
male
gz
Traceback (most recent call last):
File "/Users/luengwaiban/Desktop/meta.py", line 32, in <module>
print(m.age)
AttributeError: 'MyClass' object has no attribute 'age'
上面的代码里,MyMeta 是元类,MyClass 是使用元类实例化的类。 我在元类中的__new__()方法中的 addr 参数里添加 age 元素后,在 MyClass 实例化后是可以正常访问到 age 的。 但是现在屏蔽掉__new__()方法中的往 addr 参数里添加 age 元素的语句,将它放到__init__()方法中的 addr 参数里,却发现在 MyClass 实例化后是访问不到 age,但是将 age 绑在__init__()的 cls 上却可以访问(类似于 gender 的绑定)。
这样子我就不是很理解了,为什么在元类中的__init__()方法里,将属性添加到 attr 后,MyClass 实例化完成后却访问不到对应的属性?但是将同样的操作放到元类中的__new__()方法中却可以?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.