有没有可能做一个装饰器,当你试图用hasattr()访问它时,它会使属性变得懒惰,而不会求值?我想出了如何让它变得懒惰,但hasattr()让它过早地进行了评估。例如,
class lazyattribute:
# Magic.
class A:
@lazyattribute
def bar(self):
print("Computing")
return 5
>>> a = A()
>>> print(a.bar)
'Computing'
5
>>> print(a.bar)
5
>>> b = A()
>>> hasattr(b, 'bar')
'Computing'
5
# Wanted output: 5发布于 2009-08-18 03:21:55
到目前为止,似乎没有人提到的是,也许最好的做法是不使用hasattr()。取而代之的是EAFP (请求原谅比请求许可更容易)。
try:
x = foo.bar
except AttributeError:
# what went in your else-block
...
else:
# what went in your if hasattr(foo, "bar") block
...这显然不是临时替换,您可能需要移动一些东西,但这可能是“最好的”解决方案(当然,主观上)。
发布于 2009-08-17 07:37:26
问题是hasattr使用getattr,所以当您使用hasattr时,您的属性总是会被计算。如果你发布了你的lazyattribute魔术的代码,希望有人能推荐一种不需要hasattr或getattr的替代方法来测试属性的存在。请参阅hasattr的帮助
>>> help(hasattr)
Help on built-in function hasattr in module __builtin__:
hasattr(...)
hasattr(object, name) -> bool
Return whether the object has an attribute with the given name.
(This is done by calling getattr(object, name) and catching exceptions.)发布于 2009-08-18 04:16:43
我很好奇你为什么需要这样的东西。如果hasattr最终调用了您的“计算函数”,那么就这么做吧。你的属性到底需要多懒呢?
尽管如此,这里有一种通过检查调用函数的名称来完成此操作的相当不雅的方法。它可能会更好地编码,但我不认为它应该被认真地使用。
import inspect
class lazyattribute(object):
def __init__(self, func):
self.func = func
def __get__(self, obj, kls=None):
if obj is None or inspect.stack()[1][4][0].startswith('hasattr'):
return None
value = self.func(obj)
setattr(obj, self.func.__name__, value)
return value
class Foo(object):
@lazyattribute
def bar(self):
return 42https://stackoverflow.com/questions/1286548
复制相似问题