关于Python内置函数getattr()标准行为的疑问
关于Python内置函数getattr()标准行为的疑问
你发现的这个问题其实是那个所谓的“标准实现”写得不对!咱们一步步理清楚:
首先,Python内置getattr()的真实默认行为是这样的:
- 如果你只传前两个参数(对象和属性名),当属性不存在时,会直接抛出
AttributeError - 只要你显式传入了第三个default参数——不管这个参数的值是什么,哪怕是
None——当属性不存在时,就会返回你传的这个default值,不会抛错
那你看到的那个模拟代码问题出在哪呢?它写了if default is not None:才返回default,否则就抛错。但这个逻辑完全搞错了Python的设计:Python判断的是你有没有传default参数,而不是default的值是不是None。
举个例子,你调用getattr(test, "unknown_value", None)时,是显式传了default为None的,按照内置逻辑应该直接返回None;但那个模拟代码因为看到default是None,就直接走了raise分支,所以才会抛错。
要写出符合真实行为的模拟实现,咱们得用一个“哨兵值”来区分“用户没传default”和“用户传了default=None”的情况——比如用一个独一无二的空对象,因为正常情况下用户不可能传这个值:
def getattr(obj, name, default=object()): try: # 尝试获取属性,和内置逻辑一致 return object.__getattribute__(obj, name) except AttributeError: # 检查用户是否显式传了default参数 if default is not object(): return default # 没传default的话,才抛出原错误 raise
你把这个修正后的模拟代码代入你的测试案例,就会和内置getattr()一样,正确返回None了。
再回头看你的测试代码,内置getattr(test, "unknown_value", None)返回None是完全符合标准行为的,那个网上的“标准实现”其实是个有bug的版本,别被它误导啦!
备注:内容来源于stack exchange,提问作者NumeroUnoDE
相关产品推荐
相关产品推荐

