码迷,mamicode.com
首页 > 编程语言 > 详细

python元编程之实现定制类--使用描述符,__slots__,__new__篇

时间:2018-11-29 23:14:06      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:tuple   partial   特殊属性   自己实现   使用   sel   cti   键值   from   

问题:实现一个类,要求行为如同namedtuple:只存在给定名称的属性,不允许动态添加实例属性。

主要知识点在于: __slots__、描述符及property、__new__的使用

代码如下:

 1 """
 2 运行环境
 3 python 3.7+
 4 """
 5 from collections import namedtuple, OrderedDict
 6 
 7 #以下为要包装的对象:1个命名元组,用于存储计数,并对外传递信息
 8 Counter = namedtuple("Counter", "total put OK failed recorded keys count",
 9                      defaults=(0, 0, 0, 0, 0, 0, 0))
10 
11 class Demo:
12     """
13     使用__slots__,__new__及描述符实现定制类
14     只能使用Counter中的属性进行存取
15     """
16     #引入__slots__特殊属性用于控制实例属性
17     #_dict用于存储内部数据,此处未实现保护,可用定制描述符实现保护
18     __slots__ = list(Counter._fields)+[_dict]
19     def __new__(cls):
20         """
21         使用__new__特殊方法用于生成类实例之前配置类模板
22         因为描述符及特性(property)都是附在类上,而不是在实例上
23         """
24         for f in Counter._fields:
25             #动态生成描述符或特性,用于控制属性存取
26             #python内置的property就是特殊的描述符,可以用partialmethod包装后在此处使用.此处未展示
27             #自己实现描述符当然更具定制性
28             setattr(cls,f,Descriptor(f))
29         return super().__new__(cls)
30     def __init__(self):
31         self._dict={}
32         for f in Counter._fields:
33             self._dict[f]=0
34 
35     def update(self, n: Counter = None, **kargs):
36         """
37         使用数值累加计数器
38         当Counter与键参数同时提供时,键值为准
39         """
40         
41 #描述符实现
42 class Descriptor:
43     def __init__(self,storage_name:str):
44         self.storage_name=storage_name
45     def __set__(self,instance,value):
46         print(from descriptor..)
47         instance._dict[self.storage_name]=value
48     def __get__(self,instance,owner):
49         return instance._dict[self.storage_name]
50     
51 #也可以用以下特性工厂函数实现
52 def make_property(store_name:str)->property:
53     def getter(instance):
54         print(from property getter)
55         return instance._dict[store_name]
56     def setter(instance,value):
57         print(from property setter)
58         instance._dict[store_name]=value
59     return property(getter,setter)

补充说明,以上部分逻辑并未完整考虑和优化,只是对类定制及属性存取做实现演示。另外的实现方法可参考上篇:

python元编程之使用动态属性实现定制类--特殊方法__setattr__,__getattribute__篇 https://www.cnblogs.com/zward/p/10041162.html

python元编程之实现定制类--使用描述符,__slots__,__new__篇

标签:tuple   partial   特殊属性   自己实现   使用   sel   cti   键值   from   

原文地址:https://www.cnblogs.com/zward/p/10041453.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!