类内置attr属性

# class Cat:
# class_level = '贵族'
# def __init__(self, name, type, speed, age):
# self.name = name
# self.type = type
# self.speed = speed
# self.age = age
#
# def run(self):
# print('%s岁的%s%s正在以%s的速度奔跑' % (self.age, self.type, self.name, self.speed))
#
# def __getattr__(self, item):
# print('你找的%s属性不存在' % item)
#
# def __setattr__(self, key, value):
# print('你在设置属性')
#
# def __delattr__(self, item):
# print('你在删除属性')

# xiaohua = Cat('小花', '橘猫', '10m/s', 5)
# 你在设置属性
# 你在设置属性
# 你在设置属性
# 你在设置属性

# xiaohua.run()
# 你找的属性不存在
# 你找的属性不存在
# 你找的属性不存在
# 你找的属性不存在
# None岁的NoneNone正在以None的速度奔跑

# 可以看到__setattr__和__getattr__被触发了,为什么呢?我们上面的代码只是做了一个实例化和调用一个方法;实例化就是要找到__init__函数设置实例的数据属性,
# 所以这里__setattr__被触发了,但是__getattr__为什么被触发了呢?因为我们的__setattr__函数下面只是打印了一行,并没有任何的其它赋值操作,所以__init__里面的数据属性
# 没有被赋值,在对象调用run方法的时候就找不到self.age,self.type,self.name,self.speed这些属性,所以就会触发__getattr__方法

'''
下面总结这3个方法的使用场景:
__setattr__添加/修改属性会触发它的执行
__getattr__只有在使用点调用属性且属性不存在的时候才会触发
__delattr__删除属性的时候会触发
'''

# 如果我们在Class没有定义这3个方法,那么系统会用Python自带的内部函数,如果我们在类里面字定义了这3个函数,那么python会先调用我们自定义的这3个函数
# 上面的__getattr__之所以被触发就是因为__setattr__函数下面只是打印了一行,并没有任何的其它赋值操作

class Cat:
class_level = '贵族'
def __init__(self, name, type, speed, age):
self.name = name
self.type = type
self.speed = speed
self.age = age

def run(self):
print('%s岁的%s%s正在以%s的速度奔跑' % (self.age, self.type, self.name, self.speed))

def __getattr__(self, item):
print('你找的%s属性不存在' % item)

def __setattr__(self, key, value):
print('你在设置属性')
# self.key = value # 这种方法不行,会产生无限递归了,因为他本身self.key=value也会触发__setattr__
self.__dict__[key] = value # 我们在给对象属性赋值的时候,内部原理就是操作对象的__dict__字典,所以我们可以直接操作对象的字典实现属性赋值

def __delattr__(self, item):
print('你在删除属性')
# del self.item # 无限递归了,和上面的__setattr__原理一样
self.__dict__.pop(item)

xiaohua = Cat('小花花', '波斯猫', '10m/s', 8) # 触发__setattr__方法
# 你在设置属性
# 你在设置属性
# 你在设置属性
# 你在设置属性

xiaohua.run()
# 8岁的波斯猫小花花正在以10m/s的速度奔跑

xiaohua.weight = '5KG' # 触发__setattr__方法
# 你在设置属性
print(xiaohua.__dict__)
# {'name': '小花花', 'type': '波斯猫', 'speed': '10m/s', 'age': 8, 'weight': '5KG'}

del xiaohua.weight # 触发__delattr__方法
# 你在删除属性
print(xiaohua.__dict__)
# {'name': '小花花', 'type': '波斯猫', 'speed': '10m/s', 'age': 8}

xiaohua.abc # 触发__getattr__方法
# 你找的属性不存在


# class Foo:
# pass
#
# print(dir(Foo)) # dir()可以看到类的更多内置方法
上一篇:jQuery 效果 - 淡出


下一篇:[ASP.NET MVC] 使用CLK.AspNet.Identity提供以角色为基础的访问控制(RBAC)