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)

  • 相关阅读:
    QT源码解析(七)Qt创建窗体的过程,作者“ tingsking18 ”(真正的创建QPushButton是在show()方法中,show()方法又调用了setVisible方法)
    C++与QML混合编程实现2048
    Qt Resource系统概说(资源压缩不压缩都可以)
    QML动画概述(几十篇相关博客)
    凤年读史27:普鲁士vs德意志
    DIP、IoC、DI以及IoC容器
    WebService和AngularJS实现模糊过滤查询
    详解SpringMVC请求的时候是如何找到正确的Controller
    .NET MVC学习之模型绑定
    Unit Of Work-工作单元
  • 原文地址:https://www.cnblogs.com/lshedward/p/10415731.html
Copyright © 2011-2022 走看看