Python使用描述符实现属性类型检查的案例解析

目录
  • 1、如何使用描述符对实例属性做类型检查?
    • 实际案例:
    • 解决方案:
  • 2、代码演示

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'

到此这篇关于Python使用描述符实现属性类型检查的文章就介绍到这了,更多相关python属性类型检查内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解Python魔法方法之描述符类

    描述符类要求: 描述符就是将某种特殊类型的类的实例指派给另一个类的属性 至少要实现以下的一个方法: •__get__(self, instance, owner) –用于访问属性,它返回属性的值 •__set__(self, instance, value) –将在属性分配操作中调用,不返回任何内容 •__delete__(self, instance) –控制删除操作,不返回任何内容 eg: >>> class MyDecriptor: def __get__(self,instanc

  • Python基础详解之描述符

    一.描述符定义 描述符是一种类,我们把实现了__get__().__set__()和__delete__()中的其中任意一种方法的类称之为描述符. 描述符的作用是用来代理一个类的属性,需要注意的是描述符不能定义在被使用类的构造函数中,只能定义为类的属性,它只属于类的,不属于实例,我们可以通过查看实例和类的字典来确认这一点. 描述符是实现大部分Python类特性中最底层的数据结构的实现手段,我们常使用的@classmethod.@staticmethd.@property.甚至是__slots__

  • 详解Python描述符的工作原理

    一.前言 其实,在开发过程中,虽然我们没有直接使用到描述符,但是它在底层却无时不刻地被使用到,例如以下这些: function.bound method.unbound method 装饰器property.staticmethod.classmethod 是不是都很熟悉? 这些都与描述符有着千丝万缕的关系,这篇文章我们就来看一下描述符背后的工作原理. 二.什么是描述符? 在解释什么是「描述符」之前,我们先来看一个简单的例子. 这个例子非常简单,我们在类 A 中定义了一个类属性 x,然后打印它的

  • Python descriptor(描述符)的实现

    问题 问题1 Python是一种动态语言,不支持类型检查.当需要对一个对象执行类型检查时,可能会采用下面的方式: class Foo(object): def __init__(self,a): if isinstance(a,int): self.__a = a else: raise TypeError("Must be an int") def set_a(self,val): if isinstance(val,int): self.__a = val else: raise

  • python如何对实例属性进行类型检查

    本文实例为大家分享了python对实例属性进行类型检查的具体代码,供大家参考,具体内容如下 案例: 在某项目中,我们实现了一些类,并希望能像静态语言那样对他们的实例属性进行类型检查 p = Person() p.name = 'xi_xi'         # 必须是str p.age = 18                  # 必须是int p.height = 1.75              # 必须是float 需求: 可以对实例变量名指定类型 赋予不正确类型抛出异常 #!/usr

  • Python使用描述符实现属性类型检查的案例解析

    目录 1.如何使用描述符对实例属性做类型检查? 实际案例: 解决方案: 2.代码演示 1.如何使用描述符对实例属性做类型检查? 实际案例: 在某项目中,我们实现了一些类,并希望能像静态类型语言那样(C,C++,Java)对它们的实例属性做类型检查. p = Person() p.name = 'Bob' # 名字属性必须是str p.age = 18 # 年龄必须是int p.height = 1.83 # 身高必须是float 要求:(1)可以对实例变量名指定类型 (2)赋予不正确类型时抛出异

  • Python 的描述符 descriptor详解

    Python 在 2.2 版本中引入了descriptor(描述符)功能,也正是基于这个功能实现了新式类(new-styel class)的对象模型,同时解决了之前版本中经典类 (classic class) 系统中出现的多重继承中的 MRO(Method Resolution Order) 问题,另外还引入了一些新的概念,比如 classmethod, staticmethod, super, Property 等.因此理解 descriptor 有助于更好地了解 Python 的运行机制.

  • python的描述符(descriptor)、装饰器(property)造成的一个无限递归问题分享

    分享一下刚遇到的一个小问题,我有一段类似于这样的python代码: 复制代码 代码如下: # coding: utf-8 class A(object): @property     def _value(self): #        raise AttributeError("test")         return {"v": "This is a test."} def __getattr__(self, key):         p

  • Python中的类与对象之描述符详解

    描述符(Descriptors)是Python语言中一个深奥但却重要的一部分.它们广泛应用于Python语言的内核,熟练掌握描述符将会为Python程序员的工具箱添加一个额外的技巧.为了给接下来对描述符的讨论做一些铺垫,我将描述一些程序员可能会在日常编程活动中遇到的场景,然后我将解释描述符是什么,以及它们如何为这些场景提供优雅的解决方案.在这篇总结中,我会使用新样式类来指代Python版本. 1.假设一个程序中,我们需要对一个对象属性执行严格的类型检查.然而,Python是一种动态语言,所以并不

  • python实现装饰器、描述符

    概要 本人python理论知识远达不到传授级别,写文章主要目的是自我总结,并不能照顾所有人,请见谅,文章结尾贴有相关链接可以作为补充 全文分为三个部分装饰器理论知识.装饰器应用.装饰器延申 装饰理基础:无参装饰器.有参装饰器.functiontools.装饰器链 装饰器进阶:property.staticmethod.classmethod源码分析(python代码实现) 装饰器基础 无参装饰器 ''' 假定有一个需求是:打印程序函数运行顺序 此案例打印的结果为: foo1 function i

  • 详解Python中的Descriptor描述符类

    描述符是调和属性访问的一个类.描述符类可用来获取.设置或删除属性值.描述符对象是在类定义的时候构建在一个类中的. 一般来说,描述符是一个具有绑定行为的对象属性,其属性的访问被描述符协议方法覆写.这些方法是__get__(). __set__()和__delete__(),一个对象中只要包含了这三个方法(译者注:包含至少一个),就称它为描述符. 属性访问的默认行为是从一个对象的字典中获取 (get).设置 (set).删除 (delete) 属性.例如:a.x 的查找链始于 a.__dict__[

  • Python中类型检查的详细介绍

    前言 大家都知道Python 是一门强类型.动态类型检查的语言.所谓动态类型,是指在定义变量时,我们无需指定变量的类型,Python 解释器会在运行时自动检查. 与静态类型语言(如 C 语言)相比,这不仅仅是少写了几个类型声明字符: #include <stdlib.h> #include <stdio.h> #define BUFF 100 char* greeting(char* name){ char* msg = (char *) malloc(sizeof(char) *

  • Python描述符descriptor使用原理解析

    描述符(descriptor)是实现了__get__.__set__.__del__方法的类,进一步可以细分为两类: 数据描述符:实现了__get__和__set__ 非数据描述符:没有实现__set__ 描述符在类的属性调用中起着很重要的作用,类在调用属性时,遵守两个规则: 按照实例属性.类属性的顺序选择属性,即实例属性优先于类属性 如果在类属性中发现同名的数据描述符,那么该描述符会优先于实例属性 非数据描述符会被实例属性覆盖 class A: def __get__(self, obj, c

随机推荐