Python __getattr__、__setattr__、__delattr__

1.__ getattr __

当我们访问一个不存在的属性的时候,会抛出异常,提示我们不存在这个属性。一般访问属性异常就是__getattr__方法抛出的。
例子:

class A(object):
    def __init__(self, value):
        self.value=value
    def __getattr__(self, item):
        print("into __getattr__")
        return "can not find attr"
a = A(10)
print(a.value)
print(a.name)
"""
10
into __getattr__
can not find attr
"""

访问类里面存在的属性会正常返回值,但是如果访问一个不存在的属性最后会进入__getattr__()
在设计自己的类的时候,可以重写__getattr__()来实现一些提示功能

class Student(object):
     def __getattr__(self, attr):
         if attr in ('name', 'age', 'score'):
             print (attr)
         else:
             raise AttributeError('Unkonw attribute : %s' % attr)
student = Student()
print(student.name)
print(student.age)
print(student.score)
print(student.id)
"""
name
None
age
None
score
None

AttributeError  
AttributeError: Unkonw attribute : id
"""
class Student(object):
     def __getattr__(self, attr):
         def _func(*arg, **kwargs):
             print( arg, kwarg)

         if not attr.startswith('_'):
             _func.func_name = attr
             return _func
         raise AttributeError('Unkonw attribute : %s' % attr)
            
            
student = Student()
print(student.name)
print(student._age)

"""
<function Student.__getattr__.<locals>._func at 0x7fbc305a2ca0>

AttributeError 
<ipython-input-140-ed18ab9ef9e6> in __getattr__(self, attr)
      7             _func.func_name = attr
      8             return _func
----> 9         raise AttributeError('Unkonw attribute : %s' % attr)
     10 
     11 

AttributeError: Unkonw attribute : _age
"""
a = {'a':{'b':1}, 'b':2}
print(a['a'])
print(a['a']['b'])
print(a['b'])
"""
{'b': 1}
1
2
class Dict(dict):
    def __init__(self, *args, **kwargs):
       super(Dict, self).__init__(*args, **kwargs)

    def __getattr__(self, name):
        value =  self[name]
        if isinstance(value, dict):
            value = Dict(value)
        return value
obj = Dict(student={'age': 18}, name='ZhangSan')
print(obj)
print(obj.name)
print(obj.student)
print(obj.student.age)
"""
{'student': {'age': 18}, 'name': 'ZhangSan'}
ZhangSan
{'age': 18}
18
"""

2 __ setattr __


class A(object):
    def __init__(self, value):
        print( "into __init__")
        self.value = value
 
    def __setattr__(self, name, value):
        print ("into __setattr__")
        if value == 10:
            print( "from __init__")
        object.__setattr__(self, name, value)
 
a = A(10)
"""
into __init__
into __setattr__
from __init__
"""
print(a.value)
#10


a.value = 20
"""
into __setattr__
"""
print(a.value)
#20

注意避免死循环:

####死循环####
#在重写__setattr__和__delattr__方法的时候要尽量避免重复调用
class A(object):
    def __init__(self, value):
        self.value = value
 
    def __setattr__(self, name, value):
        self.name = value
  
### 避免死循环###

class A(object):
    def __init__(self, value):
        self.value = value
 
    def __setattr__(self, name, value):
        self.__dict__[name] = value

3. __ delattr __

a = A(20)
print(a.value)
del a.value
print(a.value)

"""
20
when can not find attribute into __getattr__
"""

参考博客1:https://blog.csdn.net/yusuiyu/article/details/87945149
参考博客2:https://www.jianshu.com/p/61c10a59fdab

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,__delattr__是一个魔法方法,用于在清除实例属性时被捕获执行。通过重写__delattr__方法,我们可以在删除属性时添加自定义的逻辑。该方法的语法很简单,其中self是所有实例方法都必须有的第一个参数,属性是要删除的属性的名称。在重写该方法时,如果要实现真正的属性删除,必须调用父的__delattr__方法,否则相关属性不会被清除。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Python __setattr__、 __getattr__、 __delattr__、__call__用法示例](https://download.csdn.net/download/weixin_38649657/12878817)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [第8.32节 Python中重写__delattr__方法捕获属性删除](https://blog.csdn.net/LaoYuanPython/article/details/96881603)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [第8.31节 Python中使用__delattr__清除属性数据](https://blog.csdn.net/LaoYuanPython/article/details/96729822)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值