This question already has an answer here:
Which is a better way to check for the existence of an attribute?
Jarret Hardie provided this answer:
if hasattr(a, 'property'):
a.property
I see that it can also be done this way:
if 'property' in a.__dict__:
a.property
Is one approach typically used more than others?
hasattr()
is the way*.a.__dict__
is ugly and it doesn't work in many cases.hasattr()
actually tries to get attribute and catchesAttributeError
internally so it works even if you define custom__getattr__()
method.To avoid requesting the attribute twice the third argument for
getattr()
could be used:You could just use a default value instead of
not_exist
sentinel if it is more appropriate in your case.I don't like
try: do_something(x.attr) \n except AttributeError: ..
it might hideAttributeError
insidedo_something()
function.*Before Python 3.1
hasattr()
suppressed all exceptions (not onlyAttributeError
) if it is not desirablegetattr()
should be used.hasattr()
is the Pythonic way to do it. Learn it, love it.Other possible way is to check whether the variable name is in
locals()
orglobals()
:I personally hate to catch exceptions in order to check something. It looks and feels ugly. It's identical to checking if a string contains only digits that way:
Instead of gently using
s.isdigit()
. Eww.Very old question but it really needs a good answer. For even a short program, I'd say use a custom function!
Here's an example. It's not perfect for all application but it is for mine, for parsing responses from countless APIs and using Django. It's easy to fix for everyone's own requirements.
There is no "best" way, because you are never just checking to see if an attribute exists; it is always a part of some larger program. There are several correct ways and one notable incorrect way.
The wrong way
Here is a demonstration which shows this technique failing:
Output:
Most of the time, you don't want to mess with
__dict__
. It's a special attribute for doing special things, and checking to see if an attribute exists is fairly mundane.The EAFP way
A common idiom in Python is "easier to ask for forgiveness than permission", or EAFP for short. You will see lots of Python code that uses this idiom, and not just for checking attribute existence.
Note that this is exactly the same idiom for opening a file that may not exist.
Also, for converting strings to integers.
Even importing optional modules...
The LBYL way
The
hasattr
method, of course, works too. This technique is called "look before you leap", or LBYL for short.(The
hasattr
builtin actually behaves strangely in Python versions prior to 3.2 with regard to exceptions -- it will catch exceptions that it shouldn't -- but this is probably irrelevant, since such exceptions are unlikely. Thehasattr
technique is also slower thantry/except
, but you don't call it often enough to care and the difference isn't very big. Finally,hasattr
isn't atomic so it could throwAttributeError
if another thread deletes the attribute, but this is a far-fetched scenario and you'll need to be very careful around threads anyway. I don't consider any of these three differences to be worth worrying about.)Using
hasattr
is much simpler thantry/except
, as long as all you need to know is whether the attribute exists. The big issue for me is that the LBYL technique looks "strange", since as a Python programmer I'm more used to reading the EAFP technique. If you rewrite the above examples so that they use theLBYL
style, you get code that is either clumsy, outright incorrect, or too difficult to write.And LBYL is sometimes outright incorrect:
If you want to write a LBYL function for importing optional modules, be my guest... it sounds like the function would be a total monster.
The getattr way
If you just need a default value,
getattr
is a shorter version oftry/except
.If the default value is expensive to construct, then you'll end up with something like this:
Or if
None
is a possible value,Conclusion
Internally, the
getattr
andhasattr
builtins just usetry/except
technique (except written in C). So they all behave the same way where it counts, and picking the right one is due to a matter of circumstances and style.The
try/except
EAFP code will always rub some programmers the wrong way, and thehasattr/getattr
LBYL code will irk other programmers. They're both correct, and there's often no truly compelling reason to pick one or the other. (Yet other programmers are disgusted that you would consider it normal for an attribute to be undefined, and some programmers are horrified that it's even possible to have an undefined attribute in Python.)