魔法方法之__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'

  

posted @   Allen_Hao  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示