Back to Blog
Python

Python hasattr: Checking Object Attributes

python hasattr: Learn how Python's hasattr() checks object attributes, how it handles exceptions, and when to prefer it over getattr or try/except.

hasattrPython builtinsattribute checkingduck typinggetattr
Illustration of Python hasattr checking whether an object contains an attribute, shown as a magnifying glass over a Python object diagram.

What hasattr() Does and Its Syntax

python hasattr is a built-in function that reports whether an object has a given attribute. It accepts two arguments: the object to inspect and the attribute name as a string. The return value is a boolean: True when the attribute exists, False when it does not.

class Config: timeout = 30 config = Config() print(hasattr(config, "timeout")) # True print(hasattr(config, "retries")) # False

The attribute name is passed as a string, which means you can check for attributes whose names are determined at runtime. This is useful when working with dynamic data, such as configuration keys or serialized object fields.

How hasattr() Works Internally

Understanding the implementation explains most of the function's behavior. hasattr() calls getattr(obj, name) and catches AttributeError. If getattr() raises AttributeError, hasattr() returns False; otherwise it returns True.

This has a subtle consequence: hasattr() returns False not only when an attribute is genuinely missing, but also when accessing the attribute raises AttributeError for any other reason. A property getter that raises AttributeError internally will make hasattr() report False, even though the attribute is defined on the class.

The Property Getter Edge Case

Consider a class where a property getter raises AttributeError because some underlying state is missing:

class User: def __init__(self, name=None): self._name = name @property def name(self): if self._name is None: raise AttributeError("name is not set") return self._name user = User() print(hasattr(user, "name")) # False

The attribute name is defined on the class, but hasattr() returns False because the getter raises AttributeError. If you use hasattr() to decide whether to access user.name, you will skip it even though the attribute exists. This can hide the real problem: the name was never set.

A more robust pattern is to check the underlying state directly, or to use getattr() with a default and handle the missing case explicitly:

name = getattr(user, "_name", None) if name is None: name = "anonymous"

hasattr() vs getattr() with a Default

getattr(obj, "attr", default) returns the attribute value if it exists, or the default value otherwise. This is often more useful than hasattr() because it gives you the value in one step.

timeout = getattr(config, "timeout", 30)

If you use hasattr() and then getattr() separately, you perform the attribute lookup twice. The object could even change between the two calls, producing a race condition in multithreaded code. Using getattr() with a default avoids both problems.

hasattr() vs try/except

When you need both the existence check and the value, a try/except block is the most explicit approach:

try: value = obj.attribute except AttributeError: value = fallback

This has two advantages over hasattr(). First, it performs a single lookup. Second, it lets you decide whether to catch only AttributeError or also other exceptions raised by a property getter. hasattr() catches AttributeError indiscriminately, which can mask bugs in property implementations.

Performance Considerations

hasattr() performs a full attribute lookup, which for class attributes involves traversing the object's __dict__ and its class's MRO. When the attribute is a property, the getter runs as well. The exception handling inside hasattr() also has a cost when the attribute is missing, because raising and catching an exception is slower than a simple lookup.

For code that checks the same attribute repeatedly, such as inside a loop, the cost adds up. If you only need the value, getattr() with a default is faster and clearer. If you need to distinguish between "attribute missing" and "attribute present but invalid," hasattr() is the wrong tool because it cannot make that distinction.

When hasattr() Is the Right Choice

hasattr() fits best when you need a quick boolean check and do not need the value. Typical cases include duck typing checks, where you verify that an object supports a method or attribute before calling it:

if hasattr(obj, "save"): obj.save()

It is also useful for optional attributes on objects from external libraries where you cannot modify the class. In those situations, hasattr() keeps the code short and readable, as long as you are aware that property getters raising AttributeError will produce a False result.

python hasattr: Practical Usage and Code Examples | RYUSLOG DEV