描述符__get__(),__set__(),__delete__()(三十七)
http://www.cnblogs.com/linhaifeng/articles/6204014.html#_label12
描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议
__get__():调用一个属性时,触发
__set__():为一个属性赋值时,触发
__delete__():采用del删除属性时,触发
class Foo: #在python3中Foo是新式类,它实现了三种方法,这个类就被称作一个描述符
def __get__(self, instance, owner):
pass
def __set__(self, instance, value):
pass
def __delete__(self, instance):
pass
描述符是干什么的:描述符的作用是用来代理另外一个类的属性的(必须把描述符定义成这个类的类属性,不能定义到构造函数中)
#描述符Str
class Str:
def __get__(self, instance, owner):
print('Str调用')
def __set__(self, instance, value):
print('Str设置...')
def __delete__(self, instance):
print('Str删除...') #描述符Int
class Int:
def __get__(self, instance, owner):
print('Int调用')
def __set__(self, instance, value):
print('Int设置...')
def __delete__(self, instance):
print('Int删除...') class People:
name=Str()
age=Int()
def __init__(self,name,age): #name被Str类代理,age被Int类代理,
self.name=name
self.age=age #何地?:定义成另外一个类的类属性 #何时?:且看下列演示 p1=People('alex',18)
'''
Str设置...
Int设置...
''' # #描述符Str的使用
p1.name # Str调用
p1.name='zhangsan' # Str设置...
del p1.name # Str删除...
#
# #描述符Int的使用
p1.age # Int调用
p1.age=18 # Int设置...
del p1.age # Int删除... # #我们来瞅瞅到底发生了什么
print(p1.__dict__) # {}
print(People.__dict__) # {'__weakref__': <attribute '__weakref__' of 'People' objects>,
# '__dict__': <attribute '__dict__' of 'People' objects>, '__doc__': None,
# '__init__': <function People.__init__ at 0x0000013E94AC5E18>, '__module__': '__main__',
# 'name': <__main__.Str object at 0x0000013E94AD81D0>, 'age': <__main__.Int object at 0x0000013E94AD8198>} # #补充
print(type(p1) == People) #type(obj)其实是查看obj是由哪个类实例化来的 True
print(type(p1).__dict__ == People.__dict__) # True
#描述符Str
class Str:
def __get__(self, instance, owner):
print('Str调用')
def __set__(self, instance, value):
print('Str设置...')
instance.__dict__['name'] = value
def __delete__(self, instance):
print('Str删除...') #描述符Int
class Int:
def __get__(self, instance, owner):
print('Int调用')
def __set__(self, instance, value):
print('Int设置...')
instance.__dict__['age'] = value
def __delete__(self, instance):
print('Int删除...') class People:
name=Str()
age=Int()
def __init__(self,name,age): #name被Str类代理,age被Int类代理,
self.name=name
self.age=age p1=People('alex',18)
print(p1.__dict__) # {'name': 'alex', 'age': 18}
描述符分两种
一 数据描述符:至少实现了__get__()和__set__()
class Foo:
def __set__(self, instance, value):
print('set')
def __get__(self, instance, owner):
print('get')
非数据描述符:没有实现__set__()
class Foo:
def __get__(self, instance, owner):
print('get')
注意事项:
一 描述符本身应该定义成新式类,被代理的类也应该是新式类
二 必须把描述符定义成这个类的类属性,不能为定义到构造函数中
三 要严格遵循该优先级,优先级由高到底分别是
1.类属性
2.数据描述符
3.实例属性
4.非数据描述符
5.找不到的属性触发__getattr__()
#描述符Str
class Str:
def __init__(self,key):
self.key = key
def __get__(self, instance, owner):
print('Str调用')
return instance.__dict__[self.key]
def __set__(self, instance, value):
print('Str设置...')
if type(value) is not str:
raise TypeError("类型错误")
instance.__dict__[self.key] = value
def __delete__(self, instance):
print('Str删除...')
instance.__dict__.pop(self.key) #描述符Int
class Int:
def __init__(self,key):
self.key = key
def __get__(self, instance, owner):
print('Int调用')
return instance.__dict__[self.key]
def __set__(self, instance, value):
print('Int设置...')
if type(value) is not int:
raise TypeError("请输入int型")
instance.__dict__['age'] = value
def __delete__(self, instance):
print('Int删除...')
instance.__dict__.pop(self.key) class People:
name=Str("name")
age=Int("age")
def __init__(self,name,age): #name被Str类代理,age被Int类代理,
self.name=name
self.age=age p1=People("zhangsan",18)
print(p1.__dict__) # {'age': 18, 'name': 'zhangsan'}
print(p1.age)
del p1.age
print(p1.__dict__) # {'age': 18}
上面代码改进:
class Typed:
def __init__(self,key, expected_type):
self.key = key
self.expected_type = expected_type
def __get__(self, instance, owner):
return instance.__dict__[self.key]
def __set__(self, instance, value):
if not isinstance(value, self.expected_type):
raise TypeError("%s is not %s" %(value, self.expected_type))
instance.__dict__[self.key] = value
def __delete__(self, instance):
instance.__dict__.pop(self.key) class People:
name=Typed("name", str)
age=Typed("age", int)
def __init__(self,name,age): #name被Str类代理,age被Int类代理,
self.name=name
self.age=age #p1=People(99,18) # TypeError: 99 is not <class 'str'>
p1=People("zhangsan",'') # TypeError: 18 is not <class 'int'>
描述符__get__(),__set__(),__delete__()(三十七)的更多相关文章
- python基础----再看property、描述符(__get__,__set__,__delete__)
一.再看property 一个静态属性property ...
- 描述符__get__,__set__,__delete__和析构方法__del__
描述符__get__,__set__,__delete__ 1.描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一 ...
- 描述符__get__,__set__,__delete__
描述符__get__,__set__,__delete__ # 描述符:1用来代理另外一个类的属性 # __get__():调用一个属性时,触发 # __set__():为一个属性赋值时触发 # __ ...
- Python类总结-描述符__get__(),__set__(),__delete__()
1 描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),set(),delete()中的一个,这也被称为描述符协议 get():调用一个属性时,触发 set():为一 ...
- python小知识-__call__和类装饰器的结合使用,数据描述符__get__\__set__\__delete__(描述符类是Python中一种用于储存类属性值的对象)
class Decorator(): def __init__(self, f): print('run in init......') self.f = f def __call__(self, a ...
- Python描述符(__get__,__set__,__delete__)简介
先说定义,这里直接翻译官方英文文档: 一般来说,描述符是具有“绑定行为”的对象属性,该对象的属性访问将会被描述符协议中的方法覆盖.这些方法是__get__(),__set__(),和__delete_ ...
- __get__ __set__ __delete__描述符
描述符就是一个新式类,这个类至少要实现__get__ __set__ __delete__方法中的一种class Foo: def __get__(self, instance, owner): pr ...
- 描述符(__get__和__set__和__delete__)
目录 一.描述符 二.描述符的作用 2.1 何时,何地,会触发这三个方法的执行 三.两种描述符 3.1 数据描述符 3.2 非数据描述符 四.描述符注意事项 五.使用描述符 5.1 牛刀小试 5.2 ...
- Python之路(第二十七篇) 面向对象进阶:内置方法、描述符
一.__call__ 对象后面加括号,触发执行类下面的__call__方法. 创建对象时,对象 = 类名() :而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()( ...
随机推荐
- DNS之BIND使用小结(Forward转发)
之前详细介绍了DNS及其在linux下的部署过程,今天再说下DNS的BIND高级特性-forwarder转发功能.比如下面一个案例:1)已经在测试环境下部署了两台内网DNS环境,DNS的zone域名为 ...
- 牛客网-小白月赛6-J-洋灰三角
题目链接https://www.nowcoder.com/acm/contest/136/J 这题我还是不找规律了,老老实实推吧,传说找规律也可以,我还是算了 递推式:f(n)=k*f(n-1)+p ...
- 树的最长链-POJ 1985 树的直径(最长链)+牛客小白月赛6-桃花
求树直径的方法在此转载一下大佬们的分析: 可以随便选择一个点开始进行bfs或者dfs,从而找到离该点最远的那个点(可以证明,离树上任意一点最远的点一定是树的某条直径的两端点之一:树的直径:树上的最长简 ...
- “耐撕团队”部署并测试onezero团队记帐本项目
耐撕团队 对onezero团队记帐本项目的部署并测试 测试指标参见下面给出的博客: http://www.ltesting.net/ceshi/ceshijishu/xncs/2014/1030/20 ...
- last individual reading task 12061183叶露婷
http://www.cnblogs.com/yltyy/p/4025426.html 1.Different people deserve different tasks; Once team ro ...
- 第三个spring冲刺第10天
进入最后阶段冲刺最后一天了,基本的需求已经完成了,最后的布局问题也解决了,我们的软件正式推出了.
- FZU软工第五次作业-词组频率分析
目录 00.前言: 01.分工: 02.PSP表格: 03.解题思路描述与设计实现说明: 解题思路简述: 关键代码 04.附加题设计与展示: 设计的创意独到之处 实现思路 实现成果展示 05.关键代码 ...
- [转载]SpringMVC的Model参数绑定方式
SpringMVC的各种参数绑定方式 http://www.cnblogs.com/HD/p/4107674.html springMVC中复杂嵌套对象.List等集合类型数据绑定 http://ww ...
- [转帖]Intel新一代Xeon完整曝光
AMD已经官宣7nm工艺的第二代EPYC霄龙服务器平台,今年上半年就会大规模出货,而在Intel这边,由于10nm工艺进展还是不够快,在服务器上还是需要14nm继续打天下,而且还有两代14nm工艺产品 ...
- js脚本 将本地图片路径转换为html
公司业务类似于电商, 因此有很多纯图片展示的商品详情页, 类似淘宝店商品页面下的多个图片组成的商品详情页, 页面很简单, 就是一大串img标签, 但是每次做详情页都要配合emmet一顿操作( 如下图 ...