Python中的属性访问与描述符

2019-05-08  本文已影响0人  拖延症旳理想主义者

1、实例通过obj.item的形式调用属性:

class User(object):

    def __init__(self, age):
        self.age = age

if __name__ == "__main__":
    user = User(23)
    # 1、User的实例通过user.age的形式访问age这个实例属性
    print(user.age)   # 23
    # 2、上面的调用形式实际使用的是getattr这个方法
    print(getattr(user, "age"))   # 23
    # 3、我们可以使用特殊属性__dict__来查看对象具有哪些属性:
    print(user.__dict__)   # {'age': 23}

2、实例对象查找属性或方法的入口getattribute

class User(object):

    def __init__(self, age):
        self.age = age

    def __getattribute__(self, item):
        """ 
        1、重写了__getattribute__方法,每次属性调用,都会由此进入,如果没有返回值,则属性调用的值都为None
        2、若没有找到则会调用__getattr__
        3、应使用super()方法来避免无限循环
        """
        print("__get__")
        return super(User, self).__getattribute__(item)


if __name__ == "__main__":
    user = User(23)
    print(user.age)

3、对象的属性控制:

class User(object):

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __getattribute__(self, item):
        """ 1、obj.item属性被调用时,会首先进入__getattribute__ """
        return super(User, self).__getattribute__(item)

    def __getattr__(self, item):
        """ 2、找不到item属性时,会调用__getattr__方法,这里可以加入自定义判断,或者抛出异常 """
        return None

    def __setattr__(self, key, value):
        """ 3、obj.key = value 给属性赋值时,会调用__setattr__ ,也可以给不存在的属性赋值 """
        return super(User, self).__setattr__(key, value)

    def __delattr__(self, item):
        """ 4、del obj.item 回收属性时,会调用__delattr__ """
        print("delattr")
        return super(User, self).__delattr__(item)

4、属性描述符:

class IntField(object):

    """ 
    单独抽离出来一个属性对象,在属性对象中定义这个属性的查找、设置、删除行为,这个属性对象就是描述符。
    其中:obj为把描述符对象作为属性的对象实例;cls为obj的类对象。

    数据描述符和非数据描述符:
    只要至少实现__get__、__set__、__delete__方法中的一个就可以认为是描述符;
    只实现__get__方法的对象是非数据描述符,意味着在初始化之后它们只能被读取;
    同时实现__get__和__set__的对象是数据描述符,意味着这种属性是可读写的。
    """

    def __init__(self, max_value, min_value):
        self.max_value = max_value
        self.min_value = min_value

    def __get__(self, obj, cls):
         """ 3、obj.value属性描述符取值的时候调用 """
        return self.value

    def __set__(self, obj, value):
        """ 2、obj.value给属性描述符赋值的时候调用 """
        if not isinstance(value, int):
            raise TypeError("只能输入数字")
        if value > self.max_value or value < self.min_value:
            raise ValueError("大小不合格")
        else:
            self.value = value

    def __delete__(self, obj):
        pass

class User(object):

    """ 1、使用属性描述符,对属性进行限制 """
    age = IntField(max_value=100, min_value=0)
    score = IntField(max_value=100, min_value=0)

if __name__ == '__main__':
    user = User()
    user.age, user.score = 0, 100
    print(user.age, user.score)
上一篇下一篇

猜你喜欢

热点阅读