python __getattr__ 和 __setattr__方法、属性私有化

Python setattr() 函数


描述
语法

setattr 函数对应函数 getatt(),用于设置属性值,该属性必须存在。

setattr 语法:

setattr(object, name, value)

参数

  • object -- 对象。
  • name -- 字符串,对象属性。
  • value -- 属性值。
返回值
实例

无。

以下实例展示了 setattr 的使用方法:

class A(object):
 bar = 1
a = A()
getattr(a, 'bar')          # 获取属性 bar 值
setattr(a, 'bar', 5)       # 设置属性 bar 值
a.bar
Out[2]: 5



__getattr__方法

拦截点号运算。当对未定义的属性名称和实例进行点号运算时,就会用属性名作为字符串调用这个方法。如果继承树可以找到该属性,则不调用此方法

[python]  view plain  copy
  1. class empty:  
  2.     def__getattr__(self, attrname):  
  3.         ifattrname =="age":  
  4.             return40  
  5.         else:  
  6.             raiseAttributeError, attrname  
  7.    
  8. x =empty()  
  9. print(x.age)       #40  
  10. print(x.name)      #error text omitted.....AttributeError, name  

这里empty类和实例x并没有属性age,所以执行x.age时,就会调用__getattr__方法,对于name也是同样。

__setattr__方法

会拦截所有属性的的赋值语句。如果定义了这个方法,self.arrt = value 就会变成self,__setattr__("attr", value).这个需要注意。当在__setattr__方法内对属性进行赋值是,不可使用self.attr = value,因为他会再次调用self,__setattr__("attr", value),则会形成无穷递归循环,最后导致堆栈溢出异常。应该通过对属性字典做索引运算来赋值任何实例属性,也就是使用self.__dict__['name'] = value.

实现属性的私有化

[python]  view plain  copy
  1. class PrivateExc(Exception):  
  2.     pass  
  3.    
  4. class Privacy:  
  5.     def__setattr__(self, attrname, value):  
  6.         ifattrname inself.privates:  
  7.             raisePrivateExc(attrname, self)  
  8.         else:  
  9.             self.__dict__[attrname]= value  
  10.    
  11. classTest1(Privacy):  
  12.     privates= ["age"]  
  13.    
  14. classTest2(Privacy):  
  15.     privates= ["name","age"]  
  16.     def__init__(self):  
  17.         self.__dict__["name"]= "sun"  
  18.    
  19. x =Test1()  
  20. y =Test2()  
  21. x.name = "Tom"         #执行成功  
  22. x.age =20              #执行失败,产生异常,该属性在privates列表内  
  23. y.name = "Mike"        #执行失败,产生异常,该属性在privates列表内  
  24. y.age =20              #执行成功  

上述方式是python实现属性私有化的首选方式。



Python Class 对象或类型通过内置成员 __dict__ 来存储成员信息。

  我们还可以通过重载 __getattr__ 和 __setattr__ 来拦截对成员的访问,需要注意的是 __getattr__ 只有在访问不存在的成员时才会被调用。

>>> class Class1:
  def __getattr__(self, name):
    print "__getattr__"
    return None
  def __setattr__(self, name, value):
    print "__setattr__"
    self.__dict__[name] = value
    
>>> a = Class1()
>>> a.x
__getattr__
>>> a.x = 123
__setattr__
>>> a.x
123

  如果类型继承自 object,我们可以使用 __getattribute__ 来拦截所有(包括不存在的成员)的获取操作。

  注意在 __getattribute__ 中不要使用 "return self.__dict__[name]" 来返回结果,因为在访问 "self.__dict__" 时同样会被 __getattribute__ 拦截,从而造成无限递归形成死循环。

>>> class Class1(object):
  def __getattribute__(self, name):
    print "__getattribute__"
    return object.__getattribute__(self, name)
  
>>> a = Class1()
>>> a.x
__getattribute__
Traceback (most recent call last):
 File "<pyshell#3>", line 1, in <module>
 a.x
 File "<pyshell#1>", line 4, in __getattribute__
 return object.__getattribute__(self, name)
AttributeError: 'Class1' object has no attribute 'x'
>>> a.x = 123
>>> a.x
__getattribute__
123




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
和__getattribute__函数是什么?它们的作用是什么? __getattr__是Python中的一个特殊方法,用于在访问一个不存在的属性时触发。当我们尝试访问一个对象的属性,而该属性不存在时,Python会调用__getattr__方法来处理这个请求。可以在__getattr__方法中自定义对不存在属性的处理逻辑,比如返回默认值或抛出异常。 __setattr__是Python中的另一个特殊方法,用于在给对象的属性赋值时触发。当我们对一个对象的属性进行赋值时,Python会调用__setattr__方法来处理这个赋值操作。可以在__setattr__方法中自定义对属性赋值的行为,比如进行一些额外的操作或进行属性值的验证。需要注意的是,在__setattr__方法中对属性进行赋值时,应该调用父类的__setattr__方法来避免引起无限递归。 __getattribute__是Python中的另一个特殊方法,用于获取对象的属性值。当我们尝试获取一个对象的属性时,不论这个属性是否存在,Python都会调用__getattribute__方法来处理这个请求。可以在__getattribute__方法中自定义对属性的获取行为,比如进行一些额外的操作或返回特定的属性值。需要注意的是,在__getattribute__方法内部访问属性时,应该使用super().__getattribute__方法来避免引起无限递归。 总结一下: - __getattr__用于处理访问不存在属性的情况,可以自定义对不存在属性的处理逻辑。 - __setattr__用于处理属性赋值的情况,可以自定义对属性赋值的行为。 - __getattribute__用于获取属性的值,可以自定义对属性获取的行为。 参考资料: 属性相关:__getattr__函数、__setattr__函数、__getattribute__函数、__setattribute__函数和__dir__函数: - 知乎 (zhihu.com) 引用中的代码示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值