• 描述符应用 -- 让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)

  • 相关阅读:
    详解MySQL中EXPLAIN解释命令(转)
    yii framework config 可以被配置的项目
    YII之yiic创建YII应用
    Yii 用户登录验证
    全选,反选,获取值ajax提交
    firefox常用插件
    file_get_contents failed to open stream: HTTP request failed(一个字符决定成败)
    linux svn服务器(一)
    js操作cookie(转载:经测试可用)
    淘宝用户api 如何获得App Key和API Secret
  • 原文地址:https://www.cnblogs.com/lshedward/p/10415731.html
Copyright © 2020-2023  润新知