Python中有三个特殊方法__getattr__、__getattribute__、__setattr__,它们都是与对象属性相关的,主要作用是为对象提供属性访问的控制。但是它们的用法和机制略有不同。
__getattr__ 与 __getattribute__:
__getattr__ 在实例访问属性时调用;而__getattribute__在每次属性访问时都会被调用。如果一个已经存在的属性被访问,__getattribute__方法会先被调用,而__getattr__方法会在__getattribute__引发 AttributeError 异常时被调用。
下面通过一个简单的例子来说明__getattr__方法的工作:
```python
class Person(object):
def __getattr__(self, name):
print(f"attribute {name} not found")
p = Person()
p.name
# 输出:attribute name not found
```
上面的代码中,我们创建了一个Person类,并重写了它的__getattr__方法。当我们在实例p上访问属性`name`时,由于该属性不存在,所以__getattr__方法被调用,并输出了一条提示消息。
再看下面的例子,我们继续使用Person类,在其__getattribute__方法中访问属性`name`:
```python
class Person(object):
def __getattribute__(self, name):
if name == 'name':
return 'Tom'
else:
return object.__getattribute__(self, name)
p = Person()
print(p.name) # 输出:Tom
```
上面的代码中,当我们在实例p上访问属性`name`时,由于该属性已经被重写的__getattribute__方法处理,直接返回了固定的字符串'Tom'。
另外需要特别注意的是,在使用__getattribute__方法时,需要特别小心不能无限递归。如下面的例子:
```python
class Person(object):
def __getattribute__(self, name):
return self.__getattribute__(name.upper())
p = Person()
print(p.name) # 递归调用导致报错:RuntimeError
```
这段代码在访问对象属性时无限递归调用导致一直执行,最终出现RuntimeError异常。
__setattr__:
__setattr__方法在给实例属性赋值时被调用,可以实现自定义赋值行为。下面是一个例子:
```python
class Person(object):
def __setattr__(self, name, value):
print(f"setting {name} to {value}")
object.__setattr__(self, name, value)
p = Person()
p.age = 25
# 输出:setting age to 25
```
上面的代码中,当我们给实例p的属性`age`赋值时,__setattr__方法被调用,并输出了一条提示信息。
总结:
以上三个方法都可以应用于对象属性的访问控制,在实际开发中常常被用来自定义对象的属性访问行为。需要注意的是,在使用时需要避免无限递归的情况,以及保证有效性和安全性。
参考文献:
- 《Python Cookbook》 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.37seo.cn/
发表评论 取消回复