When to use getattr in Python

When to use getattr in Python

Source: Dev.to

The basic idea ## Are these the same? ## Why “dynamic” matters ## Default values (avoiding crashes) ## Accessing methods dynamically ## What getattr does not do ## Final thought At some point in Python, you realize that writing object.attribute isn’t always enough. That’s where getattr comes in. This post explains what getattr really does, what it doesn’t do, and when it actually makes sense to use it. Normally, you access attributes like this: That works only if you know the attribute name at coding time. getattr lets you do the same thing, but dynamically: If the string "name" matches an attribute on p, Python returns its value. Yes, but only in this specific case: They both return the same value. So why does getattr exist? Because this is not possible with dot notation: That’s the key difference. Let’s say you have a simple class: Now imagine the attribute you want depends on runtime logic: Without getattr, you’d be forced into using conditionals: Kind of ugly, isn't it? Another important feature: safe access. If the attribute doesn’t exist, you get an AttributeError: But you can provide a fallback: Now your program continues safely. Attributes aren’t just data, methods are attributes too. If you know the attribute name in advance, you may better chose the dot notation: getattr is for flexibility, not style points. getattr isn’t about being clever. It’s about writing code that adapts at runtime instead of being locked into hardcoded assumptions. Once you see that, it becomes a very precise tool. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK: p.name Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: getattr(p, "name") Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: getattr(p, "name") CODE_BLOCK: getattr(p, "name") CODE_BLOCK: p.name getattr(p, "name") Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: p.name getattr(p, "name") CODE_BLOCK: p.name getattr(p, "name") COMMAND_BLOCK: attr = "nombre" p.attr # looks for an attribute literally called "attr" Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: attr = "nombre" p.attr # looks for an attribute literally called "attr" COMMAND_BLOCK: attr = "nombre" p.attr # looks for an attribute literally called "attr" CODE_BLOCK: attr = "name" getattr(p, attr) Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: attr = "name" getattr(p, attr) CODE_BLOCK: attr = "name" getattr(p, attr) CODE_BLOCK: class Person: def __init__(self): self.name = "Alice" self.age = 30 person = Person() Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: class Person: def __init__(self): self.name = "Alice" self.age = 30 person = Person() CODE_BLOCK: class Person: def __init__(self): self.name = "Alice" self.age = 30 person = Person() CODE_BLOCK: fields = ["name", "age"] for field in fields: print(getattr(person, field)) Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: fields = ["name", "age"] for field in fields: print(getattr(person, field)) CODE_BLOCK: fields = ["name", "age"] for field in fields: print(getattr(person, field)) CODE_BLOCK: if field == "name": print(person.name) elif field == "age": print(person.age) Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: if field == "name": print(person.name) elif field == "age": print(person.age) CODE_BLOCK: if field == "name": print(person.name) elif field == "age": print(person.age) COMMAND_BLOCK: getattr(person, "height") > AttributeError: 'Person' object has no attribute 'height' Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: getattr(person, "height") > AttributeError: 'Person' object has no attribute 'height' COMMAND_BLOCK: getattr(person, "height") > AttributeError: 'Person' object has no attribute 'height' CODE_BLOCK: getattr(person, "height", 170) Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: getattr(person, "height", 170) CODE_BLOCK: getattr(person, "height", 170) COMMAND_BLOCK: class Calculator: def add(self, x, y): return x + y calc = Calculator() method = getattr(calc, "add") print(method(2, 3)) # 5 Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: class Calculator: def add(self, x, y): return x + y calc = Calculator() method = getattr(calc, "add") print(method(2, 3)) # 5 COMMAND_BLOCK: class Calculator: def add(self, x, y): return x + y calc = Calculator() method = getattr(calc, "add") print(method(2, 3)) # 5 CODE_BLOCK: p.name Enter fullscreen mode Exit fullscreen mode - The attribute name comes from user input - Sometimes it comes from configuration - Sometimes it comes from a loop - Sometimes you don’t even know which attribute you need until runtime - Faster than dot access - A replacement for normal attribute access - Something you should use everywhere