使用描述符为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描述符的应用的更多相关文章

  1. 杂项之python描述符协议

    杂项之python描述符协议 本节内容 由来 描述符协议概念 类的静态方法及类方法实现原理 类作为装饰器使用 1. 由来 闲来无事去看了看django中的内置分页方法,发现里面用到了类作为装饰器来使用 ...

  2. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解

     1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...

  3. 【转载】Python 描述符简介

    来源:Alex Starostin 链接:www.ibm.com/developerworks/cn/opensource/os-pythondescriptors/ 关于Python@修饰符的文章可 ...

  4. python描述符descriptor(一)

    Python 描述符是一种创建托管属性的方法.每当一个属性被查询时,一个动作就会发生.这个动作默认是get,set或者delete.不过,有时候某个应用可能会有 更多的需求,需要你设计一些更复杂的动作 ...

  5. python描述符 descriptor

    descriptor 在python中,如果一个新式类定义了__get__, __set__, __delete__方法中的一个或者多个,那么称之为descriptor.descriptor通常用来改 ...

  6. Python描述符的使用

    Python描述符的使用 前言 作为一位python的使用者,你可能使用python有一段时间了,但是对于python中的描述符却未必使用过,接下来是对描述符使用的介绍 场景介绍 为了引入描述符的使用 ...

  7. Python描述符 (descriptor) 详解

    1.什么是描述符? python描述符是一个“绑定行为”的对象属性,在描述符协议中,它可以通过方法重写属性的访问.这些方法有 __get__(), __set__(), 和__delete__().如 ...

  8. python描述符和属性查找

    python描述符 定义 一般说来,描述符是一种访问对象属性时候的绑定行为,如果这个对象属性定义了__get__(),__set__(), and __delete__()一种或者几种,那么就称之为描 ...

  9. Iterator Protocol - Python 描述符协议

    Iterator Protocol - Python 描述符协议 先看几个有关概念, iterator 迭代器, 一个实现了无参数的 __next__ 方法, 并返回 '序列'中下一个元素,在没有更多 ...

  10. Python描述符以及Property方法的实现原理

    Python描述符以及Property方法的实现原理 描述符的定义: 描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实了__get__(),__set__(),__delete__()中 ...

随机推荐

  1. oracle11g导出表时空表导不出解决方案

    oracle11g用exp命令导出数据库表时,有时会发现只导出了一部分表时而且不会报错,原因是有空表没有进行导出,之前一直没有找到方法于是用最笨的方法重新建这些空表,当然在我们实际当中表的数量大时我们 ...

  2. Oozie 之 sqoop 实战

    1.创建 lib 目录并拷贝 mysql 支持包 2.修改 job.properties 文件 nameNode=hdfs://cen-ubuntu.cenzhongman.com:8020 jobT ...

  3. Java线程和多线程(七)——ThreadLocal

    Java中的ThreadLocal是用来创建线程本地变量用的.我们都知道,访问某个对象的所有线程都是能够共享对象的状态的,所以这个对象状态就不是线程安全的.开发者可以通过使用同步来保证线程安全,但是如 ...

  4. Struts2---配置文件讲解及简单登录示例

    bean 用于创建一个JavaBean实例 constant 用于Struts2默认行为标签 <!-- 配置web默认编码集,相当于HttpServletRequest.setChartacte ...

  5. P1182 数列分段Section II

    P1182 数列分段Section II 题目描述 对于给定的一个长度为N的正整数数列A[i],现要将其分成M(M≤N)段,并要求每段连续,且每段和的最大值最小. 关于最大值最小: 例如一数列4 2 ...

  6. H2数据库使用

    H2数据库使用 H2数据库介绍 H2的优势: 1.h2采用纯Java编写,因此不受平台的限制. 2.h2只有一个jar文件,十分适合作为嵌入式数据库试用. 3.性能和功能的优势 H2和各数据库特征比较 ...

  7. 四大关键步骤掌握CloudOps模型

    [TechTarget中国原创] 要让IT运维向云演进,企业必须拥抱自动化,并且改变资源预配的思考方式. 新涌现的术语CloudOps——云运维的简写,指代企业如何运行以及管理基于云的系统.并且,随着 ...

  8. 《Cracking the Coding Interview》——第9章:递归和动态规划——题目9

    2014-03-20 04:08 题目:八皇后问题. 解法:DFS解决. 代码: // 9.9 Eight-Queen Problem, need I say more? #include <c ...

  9. iphone 8 plus 红色特别版,突然自动关机无法启动

    今天早上我的iphone 8p 突然自己在床上闪动开机图标,闪了半个多小时它就光荣的自动关机了,我尝试了长按开机键,长按home+开机键15秒,通通木有用,它就是没!反!应! 于是找了售后,学到了正确 ...

  10. 课时46:魔法方法:描述符(property的原理)

    目录: 一.描述符(property的原理) 二.课时46课后习题及答案 ********************************** 一.描述符(property的原理) ********* ...