开发者社区> 问答> 正文

创建新的类或实例属性

你想创建一个新的拥有一些额外功能的实例属性类型,比如类型检查。

展开
收起
哦哦喔 2020-04-17 15:03:25 814 0
1 条回答
写回答
取消 提交回答
  • 如果你想创建一个全新的实例属性,可以通过一个描述器类的形式来定义它的功能。下面是一个例子:
    
    # Descriptor attribute for an integer type-checked attribute
    class Integer:
        def __init__(self, name):
            self.name = name
    
        def __get__(self, instance, cls):
            if instance is None:
                return self
            else:
                return instance.__dict__[self.name]
    
        def __set__(self, instance, value):
            if not isinstance(value, int):
                raise TypeError('Expected an int')
            instance.__dict__[self.name] = value
    
        def __delete__(self, instance):
            del instance.__dict__[self.name]
    一个描述器就是一个实现了三个核心的属性访问操作(get, set, delete)的类, 分别为 __get__() 、__set__() 和 __delete__() 这三个特殊的方法。 这些方法接受一个实例作为输入,之后相应的操作实例底层的字典。
    
    为了使用一个描述器,需将这个描述器的实例作为类属性放到一个类的定义中。例如:
    
    class Point:
        x = Integer('x')
        y = Integer('y')
    
        def __init__(self, x, y):
            self.x = x
            self.y = y
    当你这样做后,所有对描述器属性(比如x或y)的访问会被 __get__() 、__set__() 和 __delete__() 方法捕获到。例如:
    
    >>> p = Point(2, 3)
    >>> p.x # Calls Point.x.__get__(p,Point)
    2
    >>> p.y = 5 # Calls Point.y.__set__(p, 5)
    >>> p.x = 2.3 # Calls Point.x.__set__(p, 2.3)
    Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "descrip.py", line 12, in __set__
            raise TypeError('Expected an int')
    TypeError: Expected an int
    >>>
    作为输入,描述器的每一个方法会接受一个操作实例。 为了实现请求操作,会相应的操作实例底层的字典(__dict__属性)。 描述器的 self.name 属性存储了在实例字典中被实际使用到的key。
    
    2020-04-17 15:03:33
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
继承与功能组合 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载