python属性访问

1. 使用特殊函数__getattribute__,__getattr__,__setattr__,__delattr__

当想要获得(get)属性时,先访问__getattribute__,如果对象不存在该属性,则继续访问__getattr__

当定义或者修改一个属性时,访问__setattr__

当删除一个属性时,访问__delattr__

>>> class C:
    def __init__(self,name='zzw'):
        self.name = name
    def __getattribute__(self,name):   
        print('getattribute')
        return super().__getattribute__(name)
    def __getattr__(self,name):
        print('getattr')
    def __setattr__(self,name,value):
        print('setattr')
        super().__setattr__(name,value)
    def __delattr__(self,name):
        print('delattr')
        super().__delattr__(name)

        
>>> c = C()
setattr
>>> c.name
getattribute
'zzw'
>>> c.x
getattribute
getattr
>>> c.x = 1
setattr
>>> del c.x
delattr

2. 注意一个陷进:定义/修改属性时递归调用自身,从而进入无限循环。

这是因为在__init__中,self.width=width会调用__setattr__方法,name不是‘square’,故执行else语句self.name=value,这还是一条赋值语句,继续调用__setattr__函数。这样调用自身的递归就会运行出错。

>>> class Rectangle:
	def __init__(self,width=0,height=0):
	    self.width = width
	    self.height = height
	def __setattr__(self,name,value):
	    if name == 'square':
		    self.width = value
		    self.height = value
	    else:
		    self.name = value
	def getArea(self):
	    return self.width*self.height

	
>>> r = Rectangle()
Traceback (most recent call last):
  File "<pyshell#42>", line 1, in <module>
    r = Rectangle()
  File "<pyshell#41>", line 3, in __init__
    self.width = width
  File "<pyshell#41>", line 10, in __setattr__
    self.name = value
  File "<pyshell#41>", line 10, in __setattr__
    self.name = value
  File "<pyshell#41>", line 10, in __setattr__
    self.name = value
  [Previous line repeated 325 more times]
  File "<pyshell#41>", line 6, in __setattr__
    if name == 'square':
RecursionError: maximum recursion depth exceeded in comparison
解决方法有两个:

第一是把self.name = value这句改为super().__setattr__(name,value),父类的__setattr__函数是封装正确的,运行不会出错

第二是把self.name = value这句改为self.__dict__[name] = value

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值