gpt4 book ai didi

python - 属性错误 : undesired interaction between @property and __getattr__

转载 作者:行者123 更新时间:2023-11-28 16:26:00 25 4
gpt4 key购买 nike

我在 @property 中结合 python 中的 __getattr__() 引发了 AttributeErrors 的问题:

示例代码:

>>> def deeply_nested_factory_fn():
... a = 2
... return a.invalid_attr
...
>>> class Test(object):
... def __getattr__(self, name):
... if name == 'abc':
... return 'abc'
... raise AttributeError("'Test' object has no attribute '%s'" % name)
... @property
... def my_prop(self):
... return deeply_nested_factory_fn()
...
>>> test = Test()
>>> test.my_prop
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __getattr__
AttributeError: 'Test' object has no attribute 'my_prop'

在我的例子中,这是一个极具误导性的错误消息,因为它隐藏了 deeply_nested_factory_fn() 有错误的事实。


根据 Tadhg McDonald-Jensen 的回答中的想法,我目前最好的解决方案如下。任何关于如何去掉 AttributeError__main__. 前缀以及回溯中对 attributeErrorCatcher 的引用的任何提示都将不胜感激。

>>> def catchAttributeErrors(func):
... AttributeError_org = AttributeError
... def attributeErrorCatcher(*args, **kwargs):
... try:
... return func(*args, **kwargs)
... except AttributeError_org as e:
... import sys
... class AttributeError(Exception):
... pass
... etype, value, tb = sys.exc_info()
... raise AttributeError(e).with_traceback(tb.tb_next) from None
... return attributeErrorCatcher
...
>>> def deeply_nested_factory_fn():
... a = 2
... return a.invalid_attr
...
>>> class Test(object):
... def __getattr__(self, name):
... if name == 'abc':
... # computing come other attributes
... return 'abc'
... raise AttributeError("'Test' object has no attribute '%s'" % name)
... @property
... @catchAttributeErrors
... def my_prop(self):
... return deeply_nested_factory_fn()
...
>>> class Test1(object):
... def __init__(self):
... test = Test()
... test.my_prop
...
>>> test1 = Test1()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
File "<stdin>", line 11, in attributeErrorCatcher
File "<stdin>", line 10, in my_prop
File "<stdin>", line 3, in deeply_nested_factory_fn
__main__.AttributeError: 'int' object has no attribute 'invalid_attr'

最佳答案

如果你愿意专门使用新式类,你可以重载 __getattribute__ 而不是 __getattr__:

class Test(object):
def __getattribute__(self, name):
if name == 'abc':
return 'abc'
else:
return object.__getattribute__(self, name)
@property
def my_prop(self):
return deeply_nested_factory_fn()

现在您的堆栈跟踪将正确提及 deeply_nested_factory_fn

Traceback (most recent call last):
File "C:\python\myprogram.py", line 16, in <module>
test.my_prop
File "C:\python\myprogram.py", line 10, in __getattribute__
return object.__getattribute__(self, name)
File "C:\python\myprogram.py", line 13, in my_prop
return deeply_nested_factory_fn()
File "C:\python\myprogram.py", line 3, in deeply_nested_factory_fn
return a.invalid_attr
AttributeError: 'int' object has no attribute 'invalid_attr'

关于python - 属性错误 : undesired interaction between @property and __getattr__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36575068/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com