鱼C论坛

 找回密码
 立即注册
查看: 33|回复: 1

[已解决]关于第068讲:类和对象(XI)的例题

[复制链接]
发表于 昨天 19:48 | 显示全部楼层 |阅读模式

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

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

x
下面一段代码是该课程视频中的例子

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):
        if attrname == "FishC":
            print("I love FishC")
        else:
            raise AttributeError(attrname)

c = C("小甲鱼",18)

运行测试时出现一个奇怪现象,比如执行:
c.x
执行结果是:
        拿来吧你~
        Traceback (most recent call last):
         File "<pyshell#5>", line 1, in <module>
              c.x
          File "<pyshell#1>", line 12, in __getattr__
            raise AttributeError(attrname)
        拿来吧你~
        拿来吧你~
        AttributeError: x


为何会出现3次“拿来吧你~”,下面两次怎么回事?
最佳答案
昨天 19:52
在您的代码中,当执行 `c.x` 时,出现了三次“拿来吧你~”的输出。这是因为在属性访问和异常处理过程中,多次触发了 `__getattribute__` 方法。下面逐步解释原因:

1. 第一次“拿来吧你~”:当执行 `c.x` 时,直接触发 `__getattribute__('x')` 方法,打印第一次“拿来吧你~”。然后,`super().__getattribute__('x')` 尝试获取属性 `x`,但 `x` 不存在,因此抛出 `AttributeError`。

2. 第二次“拿来吧你~”:由于 `__getattribute__` 抛出了 `AttributeError`,Python 会尝试调用 `__getattr__` 方法。但调用 `c.__getattr__('x')` 本身也是一次属性访问(获取 `__getattr__` 方法),因此再次触发 `__getattribute__('__getattr__')`,打印第二次“拿来吧你~”。

3. 第三次“拿来吧你~”:在 `__getattr__` 方法中,执行 `raise AttributeError(attrname)` 抛出异常。在异常处理过程中(例如打印 Traceback 时),Python 可能会访问实例 `c` 的属性(如 `__class__` 用于对象表示),从而第三次触发 `__getattribute__`,打印第三次“拿来吧你~”。

总结:三次打印分别对应:
- 第一次:直接访问 `c.x`
- 第二次:获取 `__getattr__` 方法
- 第三次:异常处理中的属性访问

这是 Python 属性访问机制和异常处理交互的正常行为。如果您想避免多次触发,可以谨慎设计 `__getattribute__` 方法。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 19:52 | 显示全部楼层    本楼为最佳答案   
在您的代码中,当执行 `c.x` 时,出现了三次“拿来吧你~”的输出。这是因为在属性访问和异常处理过程中,多次触发了 `__getattribute__` 方法。下面逐步解释原因:

1. 第一次“拿来吧你~”:当执行 `c.x` 时,直接触发 `__getattribute__('x')` 方法,打印第一次“拿来吧你~”。然后,`super().__getattribute__('x')` 尝试获取属性 `x`,但 `x` 不存在,因此抛出 `AttributeError`。

2. 第二次“拿来吧你~”:由于 `__getattribute__` 抛出了 `AttributeError`,Python 会尝试调用 `__getattr__` 方法。但调用 `c.__getattr__('x')` 本身也是一次属性访问(获取 `__getattr__` 方法),因此再次触发 `__getattribute__('__getattr__')`,打印第二次“拿来吧你~”。

3. 第三次“拿来吧你~”:在 `__getattr__` 方法中,执行 `raise AttributeError(attrname)` 抛出异常。在异常处理过程中(例如打印 Traceback 时),Python 可能会访问实例 `c` 的属性(如 `__class__` 用于对象表示),从而第三次触发 `__getattribute__`,打印第三次“拿来吧你~”。

总结:三次打印分别对应:
- 第一次:直接访问 `c.x`
- 第二次:获取 `__getattr__` 方法
- 第三次:异常处理中的属性访问

这是 Python 属性访问机制和异常处理交互的正常行为。如果您想避免多次触发,可以谨慎设计 `__getattribute__` 方法。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-11-7 04:45

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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