Given the following class (with a buggy property) then what is the best foolproof way of checking that the bar property exists?
class Foo(object):
@property
def bar(self):
raise AttributeError('unforeseen attribute error!')
Both hasattr and getattr fail and only dir works:
foo = Foo()
print hasattr(foo, 'bar')
# False
try:
getattr(foo, 'bar')
print True
except AttributeError as e:
print False
# False
print 'bar' in dir(foo)
# True
The best all round solution I can think of is:
def robust_hasattr(obj, attr):
return hasattr(obj, attr) or attr in dir(obj)
Is there a better way?
If you have a buggy property, fix the bug. If raising
AttributeErroris a bug, then make the property not do that. Raising that exception is the way to signal that you should not be using that attribute.Using
dir()can be a work-around, but it is not foolproof, asdir()is a debugging aid that can both omit information and can be overridden by theobject.__dir__hook (giving your code another vector to introduce bugs). Then there is the possibility of a buggyobject.__getattr__hook, a buggyobject.__getattribute__hook, or even descriptors on the metaclass, all of which would not be detectable by usingdir().Since you are specifically looking for a property, look for the same attribute on the class of your object:
For your specific case, the above returns True:
because there indeed is such a
propertyobject on the class.