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)