魔法方法之__getattr__(), __setattr__(), 和 __delattr__
__getattr__ 当访问对象的属性不存在时被自动调用。
1 class MyObject: 2 def __init__(self): 3 self.data = {'name': 'Alice', 'age': 25} 4 self.id=1 5 6 def __getattr__(self, name): 7 print('__getattr__方法被自动调用') 8 if name in self.data: 9 return self.data[name] 10 else: 11 raise AttributeError(f"'MyObject' object has no attribute '{name}'") 12 13 obj = MyObject() 14 print(obj.id) # id属性存在,不会调用__getattr__方法 15 16 print(obj.name) # 输出:Alice 17 print(obj.age) # 输出:25 18 print(obj.gender) # 抛出 AttributeError 异常
__getattr__(), __setattr__(), 和 __delattr__()
1 ''' 2 __getattr__(), __setattr__(), 和 __delattr__() 都是 Python 的特殊方法,用于处理对象属性的访问、赋值和删除操作。 3 1. __getattr__(self, name): 4 1. 当访问一个不存在的属性时被调用。 5 2. 接受一个参数 name,表示要获取的属性名。 6 3. 可以通过该方法动态返回属性的值或抛出 AttributeError 异常。 7 8 2. __setattr__(self, name, value): 9 1. 当给对象的属性赋值时被调用。 10 2. 接受两个参数 name 和 value,分别表示属性名和要设置的值。 11 3. 可以在该方法中自定义属性赋值的行为,例如进行类型检查或触发其他操作。 12 13 3. __delattr__(self, name): 14 1. 当删除对象的属性时被调用。 15 2. 接受一个参数 name,表示要删除的属性名。 16 3. 可以在该方法中自定义属性删除的行为,例如执行一些清理操作或阻止删除某些属性。 17 18 最佳实践: 19 1. 使用 __getattr__() 方法可以实现延迟加载(lazy loading)或动态属性的功能。 20 2. 在 __setattr__() 方法中,要注意避免无限递归的问题。最好使用基类的 __setattr__() 方法来设置属性值。 21 3. 在 __delattr__() 方法中,要小心处理删除属性的逻辑,确保不会产生错误或导致对象状态不一致。 22 ''' 23 24 class MyObject: 25 def __init__(self): 26 self.data = {'name': 'Alice', 'age': 25} 27 28 def __getattr__(self, name): 29 print(f'__getattr__自动调用,name={name}') 30 if name in self.data: 31 return self.data[name] 32 else: 33 raise AttributeError(f"'MyObject' object has no attribute '{name}'") 34 35 def __setattr__(self, name, value): 36 print(f'__setattr__自动调用,name={name},value={value}') 37 if name == 'data': 38 super().__setattr__(name, value) 39 else: 40 self.data[name] = value 41 42 def __delattr__(self, name): 43 print(f'__delattr__自动调用,name={name}') 44 if name == 'data': 45 super().__delattr__(name) 46 else: 47 del self.data[name] 48 49 obj = MyObject() 50 51 # 获取属性 52 print(obj.name) # 输出:Alice 53 obj.id=1 54 print(obj.id) 55 56 # 设置属性 57 obj.age = 30 58 print(obj.age) # 输出:30 59 60 # 删除属性 61 del obj.name 62 print(obj.name) # 抛出 AttributeError 异常
执行结果:
__setattr__自动调用,name=data,value={'name': 'Alice', 'age': 25}
__getattr__自动调用,name=name
Alice
__setattr__自动调用,name=id,value=1
__getattr__自动调用,name=id
1
__setattr__自动调用,name=age,value=30
__getattr__自动调用,name=age
30
__delattr__自动调用,name=name
__getattr__自动调用,name=name
Traceback (most recent call last):
File "F:\allen_class\python\base\034魔法方法之__getattr__&&__setattr__&&__delattr__.py", line 62, in <module>
print(obj.name) # 抛出 AttributeError 异常
^^^^^^^^
File "F:\allen_class\python\base\034魔法方法之__getattr__&&__setattr__&&__delattr__.py", line 33, in __getattr__
raise AttributeError(f"'MyObject' object has no attribute '{name}'")
AttributeError: 'MyObject' object has no attribute 'name'

浙公网安备 33010602011771号