类内置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()可以看到类的更多内置方法
while True: print('studying...')
原文地址:https://www.cnblogs.com/xuewei95/p/14704621.html