This post was compiled by Programmer Hynek Schlawack, a German software engineer, from the number one post on Hacker News.

He advises against using Hasattr () unless you are writing Python 3-only code with a clear understanding of hasattr().

Under Python 2, it is not recommended to write code like this:

if hasattr(x, "y"): print(x.y) else: print("no y!" )Copy the code

It is better to do something like the following two examples:

try: print(x.y) except AttributeError: print("no y!" )Copy the code

y = getattr(x, "y", None) if y is not None: print(y) else: print("no y!" )Copy the code

This is especially true if you are not dealing with user-created classes.

One of the above uses getattr(), which treats missing attributes as None (a common case), and uses a sentinel value if you want to distinguish it from this. Getattr is no slower than hasattr() because the lookup process is exactly the same and the latter does not save the results (at least under CPython implementations).

Why nothasattr()

Using hasattr() in Python 2 is almost indistinguishable from the following code:

try: print(x.y) except: print("no y!" )Copy the code

But this hides the property:

>>> class C(object): ... @property ... def y(self): ... 0/0... >>> hasattr(C(), "y") FalseCopy the code

With third-party library classes, there is no way to determine if an attribute is a feature (or if a later update makes it a feature), so using hasattr() like this is dangerous.

You might not believe it, but there are actually replies on Hacker News from programmers who have experienced this, and hasattr() hides a very deep bug that makes tuning work very difficult.

Another reason is that using hasttr() on features executes their getters, which does not match the name of hasattr().

In Python 3, however, hasattr() does not have these problems:

>>> class C: ... @property ... def y(self): ... 0/0... >>> hasattr(C(), "y") Traceback (most recent call last): File "", line 1, in File "", line 4, in y ZeroDivisionError: division by zeroCopy the code

Therefore, pay special attention to this function when writing hybrid code that is compatible with Python 2 and 3. Also, you wouldn’t expect hasattr() to raise a ZeroDivisionError, would you?

What about AttributeError, the observant reader might ask? Indeed, if it does occur, there is no way to tell whether the property is really missing or if there is a problem with the property. This approach reduces the number of possible errors to just one, avoiding the confusing behavior differences between Python 2 and 3. .

conclusion

Of course, you can still use hasattr() in your own code, but if you change the class later, remember to also change the corresponding hasattr() to make sure you don’t make mistakes. This may save you some code, but it may add unnecessary mental baggage.