描述器的意义

Python描述器有什么用

Posted by mengxun on July 12, 2018

场景

因为Python是动态语言,所以变量不需要声明类型。而这样的话,有时候我们想做一些限制,就会比较麻烦。比如我们想在 Human 类里想对 name 这个属性做一下类型限制,可能就需要这样写:

class Human:
    @property
    def name(self):
        return self._name
    @name.setter
    def name(self, value):
        if not isinstance(value, str):
            raise ValueError("<type> must be string")
        self._name = value

问题

但是这样会有一个问题,比如我们还要对sex属性做限制,我们就得需要这样写:

class Human:
    @property
    def name(self):
        return self._name
    
    @name.setter
    def name(self, value):
        if not isinstance(value, str):
            raise ValueError("<type> must be string")
        self._name = value
        
    @property
    def sex(self):
        return self._sex

    @sex.setter
    def sex(self, value):
        if not isinstance(value, str):
            raise ValueError("<type> must be string")
        self._sex = value

如果再扩展,还需要多写很多行,这样实在是麻烦

解决办法

这个时候可以运用 Python 里的描述器的特性,可以大大简化代码:

class String:
    def __init__(self):
        self.x = str()

    def __get__(self, instance, owner):
        return self.x

    def __set__(self, instance, value):
        if not isinstance(value, str):
            raise ValueError("<type> must be str")
        self.x = value


class Human:
    name = String()
    sex = String()

这样的话只要是需要限制为str类型的属性,都可以直接使用该描述器。当属性比较多的时候,会比property的写法要减少很多代码量,而且可维护性也增强了不少,有变动的话直接修改描述器就可以处处生效了。

参考链接:https://zhuanlan.zhihu.com/p/32764345