Is it possible to make a decorator that makes attributes lazy that do not eval when you try to access it with hasattr()
? I worked out how to make it lazy, but hasattr()
makes it evaluate prematurely. E.g.,
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
It may be difficult to do. From the hasattr documentation:
The arguments are an object and a string. The result is True if the string is the name of one of the object’s attributes, False if not. (This is implemented by calling getattr(object, name) and seeing whether it raises an exception or not.)
Since attributes may be generated dynamically by a __getattr__
method, there's no other way to reliably check for their presence. For your special situation, maybe testing the dictionaries explicitly would be enough:
any('bar' in d for d in (b.__dict__, b.__class__.__dict__))
What nobody seems to have addressed so far is that perhaps the best thing to do is not to use hasattr()
. Instead, go for EAFP (Easier to Ask Forgiveness than Permission).
try:
x = foo.bar
except AttributeError:
# what went in your else-block
...
else:
# what went in your if hasattr(foo, "bar") block
...
This is obviously not a drop-in replacement, and you might have to move stuff around a bit, but it's possibly the "nicest" solution (subjectively, of course).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With