一篇文章让你彻底明白__getattr__、__getattribute__、__g...

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/

点赞(110) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部