python 属性访问的一些小知识 setattr getattr等的

众所周知,对于python的属性,可以用 . 这个东西去访问,
那么有一些python访问有关的小知识,就需要了解了。

一些BIF:
在这里插入图片描述

再来说个小知识点/:

Python super() 函数

super函数和objet理解点这里

要好好地理解上面的东西才能看懂下面的代码。

class C:
    def __getattribute__(self,name):
        print("getattribute")
        return super().__gettribute__(name)
    def __getattr__(self,name):
        print("getattr")
    def __setattr__(self,name,value):
        print('setattr')
        super().__setattr__(self,value)
    def __delattr__(self,name):
        print('delattr')
        super().__delattr__(name)

简单举例,输出结果:
在这里插入图片描述

下面是一个简单实例:

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 :
            super().__setattr__(name,value)
            #这里不用super会无限递归。

    def getArea(self ):
        return self.width*self.height


结果:

>>> r1=Rectangle()
>>> 
>>> r1.getArea()
0
>>> r1=Rectangle(4,5)
>>> r1.getArea()
20
>>> r1=Rectangle(10,10)
>>> r1.getArea()
100
>>> 
>>> r1.square= 10
>>> 
>>> f1.height
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    f1.height
NameError: name 'f1' is not defined
>>> r1.height
10
>>> r1.getArea()
100
>>> 

从菜鸟教程搬运一些干货过来:
描述
setattr() 函数对应函数 getattr(),用于设置属性值,该属性不一定是存在的。

语法
setattr() 语法:

setattr(object, name, value)
参数
object – 对象。
name – 字符串,对象属性。
value – 属性值。
返回值
无。

实例
以下实例展示了 setattr() 函数的使用方法:

对已存在的属性进行赋值:

class A(object):
… bar = 1

a = A()
getattr(a, ‘bar’) # 获取属性 bar 值
1

setattr(a, ‘bar’, 5) # 设置属性 bar 值
a.bar
5
如果属性不存在会创建一个新的对象属性,并对属性赋值:

class A():
… name = “runoob”

a = A()
setattr(a, “age”, 28)
print(a.age)
28


描述
getattr() 函数用于返回一个对象属性值。

语法
getattr 语法:

getattr(object, name[, default])
参数
object – 对象。
name – 字符串,对象属性。
default – 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError。
返回值
返回对象属性值。

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

class A(object):
… bar = 1

a = A()
getattr(a, ‘bar’) # 获取属性 bar 值
1

getattr(a, ‘bar2’) # 属性 bar2 不存在,触发异常
Traceback (most recent call last):
File “”, line 1, in
AttributeError: ‘A’ object has no attribute ‘bar2’

getattr(a, ‘bar2’, 3) # 属性 bar2 不存在,但设置了默认值
3


getattribute
__getattribute__仅在新式类中可用,重载__getattrbute__方法对类实例的每个属性访问都有效。

Python官方文档的定义

Called unconditionally to implement attribute accesses for instances of the class.

示例代码:

复制代码
class ClassA:

x = 'a'

def __init__(self):
    self.y = 'b'

def __getattribute__(self, item):
    return '__getattribute__'

if name == ‘main’:
a = ClassA()
# 使用实例直接访问存在的类属性时,会调用__getattribute__方法
# 输出结果 getattribute
print(a.x)
# 使用实例直接访问实例存在的实例属性时,会调用__getattribute__方法
# 输出结果 getattribute
print(a.y)
# 使用实例直接访问实例不存在的实例属性时,也会调用__getattribute__方法
# 输出结果 getattribute
print(a.z)
复制代码
运行结果:

getattribute
getattribute
getattribute
另外,当同时定义__getattribute__和__getattr__时,__getattr__方法不会再被调用,除非显示调用__getattr__方法或引发AttributeError异常。

示例代码(__getattr__方法不会再被调用):

复制代码
class ClassA:

def __getattr__(self, item):
    print('__getattr__')

def __getattribute__(self, item):
    print('__getatttribute__')

if name == ‘main’:
a = ClassA()
a.x
复制代码
运行结果:

getatttribute

由于__getattr__只针对未定义属性的调用,所以它可以在自己的代码中自由地获取其他属性,而__getattribute__针对所有的属性运行,因此要十分注意避免在访问其他属性时,再次调用自身的递归循环。

当在__getattribute__代码块中,再次执行属性的获取操作时,会再次触发__getattribute__方法的调用,代码将会陷入无限递归,直到Python递归深度限制(重载__setter__方法也会有这个问题)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值