鱼C论坛

 找回密码
 立即注册
查看: 1517|回复: 3

[已解决]类中使用__getattribute__魔法方法后在实例化对象中访问不存在的属性会打印3次

[复制链接]
发表于 2023-8-29 15:19:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
class C:
    def __init__(self, name, age):
        self.name = name
        self.__age = age
    def __getattribute__(self, attrname):
        print("拿来吧你")
        return super().__getattribute__(attrname)
定义类C
c = C("九歌当下",  18)
c.name
拿来吧你
'九歌当下'
c._C__age
拿来吧你
18
c.fishC
拿来吧你
Traceback (most recent call last):
  File "<pyshell#33>", line 1, in <module>
    c.fishC
  File "<pyshell#28>", line 7, in __getattribute__
    return super().__getattribute__(attrname)
拿来吧你
拿来吧你
AttributeError: 'C' object has no attribute 'fishC'

创建实例化对象小c后,访问不存在的属性fsih后,为什么会打印三次"拿来吧你"?
最佳答案
2023-8-29 17:45:28

在Python中,当你尝试访问一个对象的属性时,Python会首先调用`__getattribute__`方法。如果该属性不存在,Python会抛出`AttributeError`异常。然后,Python会尝试调用`__getattr__`方法。如果`__getattr__`方法也不存在,Python会再次抛出`AttributeError`异常。

在你的代码中,你重写了`__getattribute__`方法,并在其中添加了打印语句。因此,每次尝试访问属性时,无论该属性是否存在,都会打印一次"拿来吧你"。

然而,当你尝试访问不存在的属性`fishC`时,`super().__getattribute__(attrname)`会抛出`AttributeError`异常。这会导致Python尝试调用`__getattr__`方法。但是,因为你没有定义`__getattr__`方法,Python会再次调用`__getattribute__`方法,再次打印"拿来吧你",然后再次抛出`AttributeError`异常。这就是为什么会打印三次"拿来吧你"的原因。

如果你不希望在访问不存在的属性时打印三次"拿来吧你",你可以在`__getattribute__`方法中捕获`AttributeError`异常,如下所示:
class C:
    def __init__(self, name, age):
        self.name = name
        self.__age = age
    def __getattribute__(self, attrname):
        print("拿来吧你")
        try:
            return super().__getattribute__(attrname)
        except AttributeError:
            pass  # 或者你可以在这里处理异常,例如返回一个默认值

这样,当你尝试访问不存在的属性时,只会打印一次"拿来吧你"。

或者定义 __getattr__ 方法:
class C:
    def __init__(self, name, age):
        self.name = name
        self.__age = age
    def __getattribute__(self, attrname):
        print("拿来吧你")
        return super().__getattribute__(attrname)
    def __getattr__(self, attrname):
        pass
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-29 17:45:28 | 显示全部楼层    本楼为最佳答案   

在Python中,当你尝试访问一个对象的属性时,Python会首先调用`__getattribute__`方法。如果该属性不存在,Python会抛出`AttributeError`异常。然后,Python会尝试调用`__getattr__`方法。如果`__getattr__`方法也不存在,Python会再次抛出`AttributeError`异常。

在你的代码中,你重写了`__getattribute__`方法,并在其中添加了打印语句。因此,每次尝试访问属性时,无论该属性是否存在,都会打印一次"拿来吧你"。

然而,当你尝试访问不存在的属性`fishC`时,`super().__getattribute__(attrname)`会抛出`AttributeError`异常。这会导致Python尝试调用`__getattr__`方法。但是,因为你没有定义`__getattr__`方法,Python会再次调用`__getattribute__`方法,再次打印"拿来吧你",然后再次抛出`AttributeError`异常。这就是为什么会打印三次"拿来吧你"的原因。

如果你不希望在访问不存在的属性时打印三次"拿来吧你",你可以在`__getattribute__`方法中捕获`AttributeError`异常,如下所示:
class C:
    def __init__(self, name, age):
        self.name = name
        self.__age = age
    def __getattribute__(self, attrname):
        print("拿来吧你")
        try:
            return super().__getattribute__(attrname)
        except AttributeError:
            pass  # 或者你可以在这里处理异常,例如返回一个默认值

这样,当你尝试访问不存在的属性时,只会打印一次"拿来吧你"。

或者定义 __getattr__ 方法:
class C:
    def __init__(self, name, age):
        self.name = name
        self.__age = age
    def __getattribute__(self, attrname):
        print("拿来吧你")
        return super().__getattribute__(attrname)
    def __getattr__(self, attrname):
        pass
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-7 21:00:45 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-14 21:36:47 | 显示全部楼层
为什么访问不存在的属性`fishC`时,`super().__getattribute__(attrname)`会抛出`AttributeError`异常呢?抛出异常的话,代码执行不应该中断吗?怎么还会继续执行代码呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-15 02:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表