Python使用描述符实现属性类型检查的案例解析
作者:AllardZhao 时间:2022-07-30 00:39:15
1、如何使用描述符对实例属性做类型检查?
实际案例:
在某项目中,我们实现了一些类,并希望能像静态类型语言那样(C,C++,Java)对它们的实例属性做类型检查。
p = Person()
p.name = 'Bob'# 名字属性必须是str
p.age = 18 # 年龄必须是int
p.height = 1.83# 身高必须是float
要求:(1)可以对实例变量名指定类型
(2)赋予不正确类型时抛出异常
解决方案:
使用描述符来实现需要类型检查的属性:分别实现__get__, __set__,__delete__方法,在__set__内使用isinstance函数做类型检查。
拓展:静态类型语言变量只能引用一种确定类型的对象并且不能改变。类型检查是由编译器在编译阶段完成的,对于Python动态类型语言来讲一个变量可以引用任意类型的对象并且可以实时发生改变,也就是解释器不能完成类型检查,只能自己去实现。
什么是描述符?描述符就是包含__get__, __set__,__delete__这样方法的类,这三个方法只要包含其中一个那它就是描述符。
实例属性就是在一个类中将另一个类的实例作为该类的一个数属性。
2、代码演示
(1)描述符定义和访问流程介绍
class Descriptor(object):
def __get__(self, instance, cls):
# instance用于区分使用类访问x,还是使用实例访问x
print('in __get__', instance, cls)
return instance.__dict__['x']
def __set__(self, instance, value):
# 在set中对于类型进行检查
print('in __set__')
instance.__dict__['x'] = value
def __delete__(self, instance):
print('in __del__')
class A(object):
# 在类中定义一个类属性x
x = Descriptor()
a = A()
# 会被Descriptor的__get__方法所截获
print(a.x)
# 直接使用类A访问类属性,instance会被传入None
print(A.x)
# 会被Descriptor的__set__方法所截获
a.x = 5
# 会被Descriptor的__del__方法所截获
del a.x
'''
通常来说在描述符这些方法当中访问的是instance.__dict__这个字典,
也就是对于它的真正属性进行操作。
'''
a = A()
a.x = 5
print(a.__dict__)
(2)实现使用描述符检查实例属性类型
class Attr(object):
def __init__(self, name, type_):
self.name = name
self.type_ = type_
def __get__(self, instance, cls):
return instance.__dict__[self.name]
def __set__(self, instance, value):
# 对字段类型做检测
if not isinstance(value, self.type_):
raise TypeError('expected an %s' % self.type_)
instance.__dict__[self.name] = value
def __delete__(self, instance):
del instance.__dict__[self.name]
class Person(object):
# 定义一个name字段,申请描述符实例
name = Attr('name', str)
age = Attr('age', int)
height = Attr('height', float)
p = Person()
p.name = 'Bob'
print(p.name)
# age赋值字符串类型抛出异常错误
# p.age = '17'
来源:https://blog.csdn.net/qq_37189082/article/details/124739329
标签:python,描述符,属性类型检查


猜你喜欢
简单了解Django应用app及分布式路由
2023-08-30 19:29:47

Python实现仿射密码的思路详解
2021-04-17 22:32:00

平面设计中的文字设计
2009-01-15 12:09:00
python GUI库图形界面开发之PyQt5信号与槽的高级使用技巧装饰器信号与槽详细使用方法与实例
2022-11-27 15:06:22

SQL中去除重复数据的几种方法汇总(窗口函数对数据去重)
2024-01-14 06:54:35

Google logo “我的中国”谷歌国际少年绘画大赛小学1-3年级
2008-12-19 12:26:00

网页制作,改变你的思维方式
2007-09-29 13:12:00
如何获得ADO的连接信息?
2009-11-23 20:33:00
order by newid() 各种数据库随机查询的方法
2024-01-19 16:53:14
修改并编译golang源码的操作步骤
2024-05-02 16:26:23

利用Pytorch实现ResNet网络构建及模型训练
2022-02-24 19:57:59
正则表达式简介
2007-08-12 18:01:00
eclipse创建python项目步骤详解
2021-01-15 00:40:47

深入理解Python中的元类(metaclass)
2021-02-25 22:10:00
PHP实现获取客户端IP并获取IP信息
2023-06-18 08:34:26
node.js的事件机制
2024-05-03 15:58:31
mysql5.7.21启动异常的修复方法
2024-01-24 20:33:16

pandas DataFrame 根据多列的值做判断,生成新的列值实例
2023-11-11 01:48:11

简单解决Python文件中文编码问题
2021-08-21 22:58:43

使用Python对MySQL数据操作
2024-01-16 16:04:26