学习元类的时候,对__prepare__
不是很理解,书上讲解的也不是很详细,最后通过查看stackoverflow的一些帖子对该方法有了一些理解,记录如下:
先看代码:
''' 遇到问题没人解答?小编创建了一个Python学习交流: 寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书! ''' class member_table(dict): def __init__(self): self.member_names = [] def __setitem__(self, key, value): if key not in self: self.member_names.append(key) dict.__setitem__(self, key, value) class OrderedClass(type): @classmethod def __prepare__(metacls, name, bases): classdict = member_table() print("prepare return dict id is:", id(classdict)) return classdict def __new__(metacls, name, bases, classdict): print("new get dict id is:", id(classdict)) result = type.__new__(metacls, name, bases, dict(classdict)) result.member_names = classdict.member_names print("the class's __dict__ id is:", id(result.__dict__)) return result def __init__(cls, name, bases, classdict): print("init get dict id is ", id(classdict)) super().__init__(name, bases, classdict) class MyClass(metaclass=OrderedClass): def method1(self): pass def method2(self): pass print("MyClass locals() id is ", id(locals()))
输出为:
prepare return dict id is: 28 MyClass locals() id is 28 new get dict id is: 28 the class's __dict__ id is: 00 init get dict id is 28
可见,执行顺序为:
prepare(创建命名空间)-> 依次执行类定义语句 -> new(创建类)-> init(初始化类)
元类定义了prepare以后,会最先执行prepare方法,返回一个空的定制的字典,然后再执行类的语句,类中定义的各种属性被收集入定制的字典,最后传给new和init方法。
再来看其它输出:
MyClass.member_names ['__module__', '__qualname__', 'method1', 'method2'] MyClass.attr1 = 'attr1' MyClass.__dict__ mappingproxy({
'__dict__': <attribute '__dict__' of 'MyClass' objects>, '__doc__': None, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, 'attr1': 'attr1', 'member_names': ['__module__', '__qualname__', 'method1', 'method2'], 'method1': <function __main__.MyClass.method1>, 'method2': <function __main__.MyClass.method2>}) id(MyClass.__dict__) 64 MyClass.member_names ['__module__', '__qualname__', 'method1', 'method2']
上面的例子,在new方法中,dict被替换成一个普通的dict。所以MyClass.member_names
不会记录class创建以后新增的属性。同时__dict__
属性是类命名空间的一个代理,每次查看其id都不同。
3.6版本以前,prepare方法主要用来返回一个orderdict对象,以保存类中属性的添加顺序。而3.6版本以后,默认已经是保持顺序的了。
今天的文章
python3 元类_python定义元组分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/61085.html