python2/python3中__get__、 __getattr__、 __getatrribute__的区别

本文探讨了Python2经典类与新式类及Python3类在使用__get__、__getattr__和__getattribute__方法时的行为差异。通过示例代码展示了这些方法在不同类型的类中如何工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

python2的类分为经典类和新式类,派生自object的类都是新式类,python3的类都是新式类,默认派生自object。python2的__get__、 __getattr__、 __getatrribute__函数和python3的略有不同,下面分点说明。

1.__get__(self, instance, owner)

__get__(self, instance, owner)函数只有在新式类中有意义,在经典类中无意义。在新式的class中,如果定义了__get__,则这个类可以成为descriptor。owner为把descriptor设为类属性的class, instance为该class的实例。如果通过class访问descriptor,则instance为None。
测试代码如下图所示,左中右分别为python2经典类、python2新式类、python3的类:


有图可以看出,__get__在python2经典类中无意义,在python2新式类中和python3的意义一样。

2.__getattr__(self,  attr)、 __getatrribute__(self, attr)

(1)经典类中的__getattr__,__getatrribute__

__getatrribute__函数在经典类中无意义,__getattr__函数在经典类中有意义。测试代码如下。
>>> class A:
	def __init__(self, x):
		self.x = x
	def __getattr__(self, attr):
		return 'getattr: ', attr

	
>>> class B:
	def __init__(self, x):
		self.x = x
	def __getattribute__(self, attr):
		return 'getattribute: ', attr

	
>>> a = A('foo'); b = B('bar')
>>> 
>>> a.x
'foo'
>>> b.x
'bar'
>>> a.y
('getattr: ', 'y')
>>> b.y

Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    b.y
AttributeError: B instance has no attribute 'y'
>>> 

(2)新式类中的__getattr__,__getatrribute__

同时定义了__getattr__和__getattribute__的话,访问类实例属性只会调用__getattribute__,不管该属性是否存在。只定义了__getattr__没有定义__getattribute__的情况下,访问存在的类实例属性不会调用__getattr__,会返回该属性的值;访问不存在的实例属性的话会调用__getattr__。测试代码见下图,左边为python2新式类,右边为python3.



`__getattr__`和`__getattribute__`是Python中特殊的方法,用于处理对象的属性访问和获取。 `__getattr__`用于在对象实例的属性不存在时被调用,通常在动态获取属性的情况下使用。当我们尝试访问一个对象上不存在的属性时,Python解释器会自动调用`__getattr__`方法。我们可以在这个方法中定义对不存在属性的处理逻辑,比如返回默认值或者触发异常。 下面是一个示例: ``` class MyClass: def __getattr__(self, name): return f"Attribute {name} does not exist." obj = MyClass() print(obj.some_attr) # Output: Attribute some_attr does not exist. ``` `__getattribute__`用于在对象实例的属性被访问时被调用。与`__getattr__`不同,`__getattribute__`会在所有属性访问上被调用,无论属性是否存在。我们可以通过在`__getattribute__`方法中自定义属性访问的行为,比如在访问属性前执行一些操作或返回特定的值。 下面是一个示例: ``` class MyClass: def __getattribute__(self, name): print(f"Accessing attribute {name}") return super().__getattribute__(name) obj = MyClass() print(obj.some_attr) # Output: # Accessing attribute some_attr # None ``` 注意,使用`__getattribute__`时需要谨慎,因为在方法内部访问同个实例的其他属性时可能会触发无限递归调用。在这种情况下,可以通过使用`super()`来避免无限递归。 综上所述,`__getattr__`和`__getattribute__`是Python中用于处理对象属性访问和获取的特殊方法,分别用于处理不存在属性和所有属性的访问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值