python描述符的应用
使用描述符为python实现类型检测
class Typed: def __get__(self, instance, owner): print(instance) print(owner) def __set__(self, instance, value): pass class Girl: name = Typed() def __init__(self, name, age): self.name = name # 我希望传入的name是str self.age = age # 我希望传入的age是int g = Girl("satori", 18) g.name ''' <__main__.Girl object at 0x03D28430> <class '__main__.Girl'> ''' # 可以看到当我们获取被代理的值,会触发get方法,instance就是Girl的实例对象 # owner则是Girl这个类
class Typed: def __get__(self, instance, owner): pass def __set__(self, instance, value): print(instance) print(value) class Girl: name = Typed() def __init__(self, name, age): self.name = name # 我希望传入的name是str self.age = age # 我希望传入的age是int g = Girl("satori", 18) ''' <__main__.Girl object at 0x03D28430> satori ''' # 可以看到当我们给被代理的值赋值的时候,会触发set方法,instance就是Girl的实例对象 # value则是我们赋的值
class Typed: def __init__(self, key): self.key = key def __get__(self, instance, owner): return instance.__dict__[self.key] def __set__(self, instance, value): instance.__dict__[self.key] = value def __delete__(self, instance): instance.__dict__.pop(self.key) class Girl: name = Typed("name") age = Typed("age") def __init__(self, name, age): self.name = name self.age = age g = Girl("satori", 18) print(g.__dict__) g.name = "mashiro" print(g.__dict__) del g.name print(g.__dict__) ''' {'name': 'satori', 'age': 18} {'name': 'mashiro', 'age': 18} {'age': 18} ''' # 等于说 我饶了一圈,并没有直接将属性添加的字典里面,而是向上找了代理,让代理帮我把属性添加的字典里面去
那么,接下来就可以实现类型检测了
class Typed: def __init__(self, key, except_type): self.key = key self.except_type = except_type def __get__(self, instance, owner): return instance.__dict__[self.key] def __set__(self, instance, value): if isinstance(value, self.except_type): instance.__dict__[self.key] = value else: raise Exception(f"{self.key} must be type {self.except_type}") def __delete__(self, instance): instance.__dict__.pop(self.key) class Girl: name = Typed("name", str) age = Typed("age", int) def __init__(self, name, age): self.name = name self.age = age g = Girl("satori", 18) print(g.__dict__) # {'name': 'satori', 'age': 18} try: import traceback g = Girl("satori", "18") except Exception: print(traceback.format_exc()) ''' Exception: age must be type <class 'int'> ''' # 于是我们便手动实现了python的类型检测
类的装饰器
# 装饰器不仅可以给函数用,还可以给类用 def deco(obj): print("======") return obj @deco class Girl: def __init__(self, name, age): self.name = name self.age = age g = Girl("satori", 18) print(g.__dict__) ''' ====== {'name': 'satori', 'age': 18} '''
描述符实现property
class LazeProperty: def __init__(self, func): self.func = func def __get__(self, instance, owner): # 如果是类调用,那么instance为空 if instance is None: return self res = self.func(instance) setattr(instance, self.func.__name__, res) # 将值设进去,如果有从字典里面找,没有再计算 return res class Girl: def __init__(self, name, age): self.name = name self.age = age @LazeProperty # info = LazeProperty(info) def info(self): return f"my name is {self.name},age is {self.age}" g = Girl("satori", 18) print(g.info) # my name is satori,age is 18 print(Girl.info) # <__main__.LazeProperty object at 0x04EF3910>
python描述符的应用的更多相关文章
- 杂项之python描述符协议
杂项之python描述符协议 本节内容 由来 描述符协议概念 类的静态方法及类方法实现原理 类作为装饰器使用 1. 由来 闲来无事去看了看django中的内置分页方法,发现里面用到了类作为装饰器来使用 ...
- python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解
1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...
- 【转载】Python 描述符简介
来源:Alex Starostin 链接:www.ibm.com/developerworks/cn/opensource/os-pythondescriptors/ 关于Python@修饰符的文章可 ...
- python描述符descriptor(一)
Python 描述符是一种创建托管属性的方法.每当一个属性被查询时,一个动作就会发生.这个动作默认是get,set或者delete.不过,有时候某个应用可能会有 更多的需求,需要你设计一些更复杂的动作 ...
- python描述符 descriptor
descriptor 在python中,如果一个新式类定义了__get__, __set__, __delete__方法中的一个或者多个,那么称之为descriptor.descriptor通常用来改 ...
- Python描述符的使用
Python描述符的使用 前言 作为一位python的使用者,你可能使用python有一段时间了,但是对于python中的描述符却未必使用过,接下来是对描述符使用的介绍 场景介绍 为了引入描述符的使用 ...
- Python描述符 (descriptor) 详解
1.什么是描述符? python描述符是一个“绑定行为”的对象属性,在描述符协议中,它可以通过方法重写属性的访问.这些方法有 __get__(), __set__(), 和__delete__().如 ...
- python描述符和属性查找
python描述符 定义 一般说来,描述符是一种访问对象属性时候的绑定行为,如果这个对象属性定义了__get__(),__set__(), and __delete__()一种或者几种,那么就称之为描 ...
- Iterator Protocol - Python 描述符协议
Iterator Protocol - Python 描述符协议 先看几个有关概念, iterator 迭代器, 一个实现了无参数的 __next__ 方法, 并返回 '序列'中下一个元素,在没有更多 ...
- Python描述符以及Property方法的实现原理
Python描述符以及Property方法的实现原理 描述符的定义: 描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实了__get__(),__set__(),__delete__()中 ...
随机推荐
- java实时监听日志写入kafka(多目录)
目的 实时监听多个目录下的日志文件,如有新文件切换到新文件,并同步写入kafka,同时记录日志文件的行位置,以应对进程异常退出,能从上次的文件位置开始读取(考虑到效率,这里是每100条记一次,可调整) ...
- Android字体大小怎么自适应不同分辨率?
今天有人问我,android系统不同分辨率,不同大小的手机,字体大小怎么去适应呢?其实字体的适应和图片的适应是一个道理的. 一. 原理如下: 假设需要适应320x240,480x320分辨率.在res ...
- php中utf-8转unicode
public function utf8_unicode($str) { $unicode = array(); $values = array(); $lookingFor = 1; for ($i ...
- webstrom11 vue插件配置
直接上图 1. 安装vue插件 2.添加模板 3.指定模板类型 最新的是插件 是 vue.js 创建完 Vue File 文件后 需要在 下面这里关联一下
- Oz代码梳理
https://files.cnblogs.com/files/gushiren/oz%E6%B5%81%E7%A8%8B%E5%9B%BE.pdf https://files.cnblogs.com ...
- 洛谷P1331海战
题目描述 在峰会期间,武装部队得处于高度戒备.警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞机.此外,巡洋船只和舰队将被派去保护海岸线. 不幸的是因为种种原因,国防海军部仅有很少的 ...
- django的聚合函数和aggregate、annotate方法使用
支持聚合函数的方法: 提到聚合函数,首先我们要知道的就是这些聚合函数是不能在django中单独使用的,要想在django中使用这些聚合函数,就必须把这些聚合函数放到支持他们的方法内去执行.支持聚合函数 ...
- 通过nbviwer在线分享python notebook
在数据科学计算中,jupyter-notebook是一个很得力的助手,但是Notebook写完之后如何与他人分享呢?我们可以使用nbviwer. 具体思路: 具体的方法如下: 本地编写ipython ...
- 再理一下prerouting和postrouting等插入点
这些地方的准确翻译是hook点(hook点是一个土的说法,学名叫rule chain,规则链)这些规则链是内核netfilter架构布置在内核里面的,然后iptables是利用了这套基础架构,想起了内 ...
- POJ 2195 Going Home | 带权二分图匹配
给个地图有人和房子 保证人==房子,每个人移动到房子处需要花费曼哈顿距离的代价 问让人都住在房子里最小代价 显然是个带权二分图最大匹配 转化成以一个网络,规定w是容量,c是代价 1.S向人连边,w=1 ...