zoukankan      html  css  js  c++  java
  • 描述符应用 -- 让python变成一个强类型的语言

    众所周知,python是一门弱类型的语言,变量可以随意赋值成任意类型,但是通过描述符,我们可以把数据变成强类型的。

    我们为数据设置数据描述符,因为数据描述的优先级大于实例属性,所以在给数据赋值的时候会优先出发数据描述符。

    普通版

    class Typed:
        def __init__(self, name, expected_type):
            self.name = name
            self.expected_type = expected_type
    
        def __get__(self, instance, owner):
            if instance is None:
                return self  # 如果实例化用People.name调用的话,就返回Typed的实例name
            return instance.__dict__[self.name]
    
        def __set__(self, instance, value):
            if not isinstance(value, self.expected_type):
                raise TypeError('Type error')
            instance.__dict__[self.name] = value
    
        def __delete__(self, instance):
            instance.__dict__.pop(self.name)
    
    
    class People:
        name = Typed('name', str)
        age = Typed('age', int)
        salary = Typed('salary', float)
    
        def __init__(self, name, age, salary):
            self.name = name
            self.age = age
            self.salary = salary
    
    
    # p1 = People(123, 18, 3333.3)  # TypeError: Type error
    # p1=People('egon','18',3333.3) # TypeError: Type error
    # p1=People('egon',18,3333)  # TypeError: Type error
    
    p1 = People('egon', 18, 3333.33)  # 正确

    用类的装饰器实现

    先回顾一下setattr的语法

    语法

    setattr() 语法:

    setattr(object, name, value)

    参数

    • object -- 对象。
    • name -- 字符串,对象属性。
    • value -- 属性值。
    class Typed:
        def __init__(self, name, expected_type):
            self.name = name
            self.expected_type = expected_type
    
        def __get__(self, instance, owner):
            if instance is None:
                return self
            return instance.__dict__[self.name]
    
        def __set__(self, instance, value):
            if not isinstance(value, self.expected_type):
                raise TypeError('type error')
            instance.__dict__[self.name] = value
    
        def __delete__(self, instance):
            self.__dict__.pop(self.name)
    
    
    def typeassert(**kwargs):
        def decorator(cls):
            for name, expected_type in kwargs.items():
                setattr(cls, name, Typed(name, expected_type))
            return cls
    
        return decorator
    
    
    @typeassert(name=str, age=int, salary=float)
    class People:
        def __init__(self, name, age, salary):
            self.name = name
            self.age = age
            self.salary = salary
    
    
    p1 = People('edward', 18, 30000.00)

  • 相关阅读:
    从零开始学习SSH框架笔记之一 初识SSH框架及下载地址
    CentOS 6.0 升级内核步骤、方法
    解决Ubuntu详细信息中图形显示为未知的情况
    【Oracle XE系列之二】Oracle XE创建表空间、创建用户以及授权、查看权限
    排序算法大总结
    我的vimrc 设置
    你的c++学的怎么样?
    腾讯的笔试题一道
    一道递归算法题
    vc6 bug真多 写c++别用vc6
  • 原文地址:https://www.cnblogs.com/lshedward/p/10415731.html
Copyright © 2011-2022 走看看