|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
添加了class C的__getattribute__方法,执行代码后why被打印了三次
代码如下:
- <div>>>> class C:
- <div>... def __init__(self,name,age):
- ... self.name = name
- ... self.__age = age
- ... def __getattribute__(self, attrname):
- ... print("why")
- ... return super().__getattribute__(attrname)
- ... def __getattr__(self,attrname):
- ... if attrname == "lol":
- ... print("lol")
- ... else:
- ... raise AttributeError(attrname)
- ...
- ...
- >>> c = C("yzh",16)
- >>> c.x
- why
- Traceback (most recent call last):
- File "<pyshell#3>", line 1, in <module>
- c.x
- File "<pyshell#1>", line 12, in __getattr__
- raise AttributeError(attrname)
- why
- why
- AttributeError: x</div></div>
复制代码
我以为是idle的问题,于是又到pycharm的控制台执行,结果打印的why更多了
- <div>
- class C:
- def __init__(self, name, age):
- self.name = name
- self.__age = age
- def __getattribute__(self, attrname):
- print("why")
- return super().__getattribute__(attrname)
- def __getattr__(self, attrname):
- if attrname == "lol":
- print("lol")
- else:
- raise AttributeError(attrname)
- c = C("yzh",16)
- why
- why
- why
- why
- why
- why
- why
- why
- why
- why
- why
- why
- why
- why
- why
- why
- why
- why
- why
- why
- why</div>
复制代码 并且是在刚实例化这个类的时候就打印了,有大佬能解答一下是什么问题吗?版本是python3.14.0
你好!我来解释一下为什么 __getattribute__ 方法会导致 "why" 被多次打印。
首先, __getattribute__ 方法在每次访问对象的任何属性时都会被调用(包括内部属性)。你的代码中,这个方法被重写为每次调用时都打印 "why",然后通过 super().__getattribute__(attrname) 返回属性值。
在 IDLE 中执行 c.x 时,"why" 被打印三次的原因如下:
- 第一次打印:直接访问 c.x 触发 __getattribute__("x")。
- 第二次和第三次打印:当属性 x 不存在时,Python 会调用 __getattr__("x"),但在这个过程中,异常处理或 Traceback 显示可能会额外访问对象的其他属性(例如 __class__ 或 __dict__),从而再次触发 __getattribute__。
在 PyCharm 控制台中,实例化对象时打印更多次 "why",是因为控制台环境通常会立即调用对象的 __repr__ 方法(用于显示对象),而默认的 __repr__ 会访问多个基础属性(如 __class__、 __dict__ 等),每次访问都会触发 __getattribute__。
简单来说,任何属性访问(包括 Python 内部操作)都会导致 "why" 被打印。如果你不希望这样,可以调整 __getattribute__ 的实现,例如避免在访问特定属性时打印。
示例代码修改(避免无限递归):
- class C:
- def __init__(self, name, age):
- self.name = name
- self.__age = age
- def __getattribute__(self, attrname):
- # 只在访问非特殊属性时打印
- if not attrname.startswith('__'):
- print("why")
- return super().__getattribute__(attrname)
- def __getattr__(self, attrname):
- if attrname == "lol":
- print("lol")
- else:
- raise AttributeError(attrname)
复制代码
这样可能会减少不必要的打印,但注意这只是一个示例,实际使用中需根据需求调整。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
|
|