Summary: in this tutorial, you’ll learn how to use the Python getattr() function to get a named attribute of an object.
Introduction to Python getattr() function #
The getattr() function allows you to get the value of the named attribute of an object. Here’s the syntax of the getattr() function:
getattr(object, name[, default])The getattr() function accepts three parameters:
objectis the object from which you want to get the value of a named attribute.nameis a string that specifies the attribute name of the object.default: if the named attribute doesn’t exist in the object, thegetattr()function returns the default. If you omit the default and the named attribute doesn’t exist, the function will raise anAttributeErrorexception.
Python getattr() function example #
The following example illustrates how to use the getattr() to get the attribute values of an object:
class Member:
def __init__(self, name, email):
self.name = name
self.email = email
member = Member('John Doe', '[email protected]')
name = getattr(member, 'name')
print(name) # ? John Doe
email = getattr(member, 'email')
print(name) # ? [email protected]
age = getattr(member, 'age')
print(age) # ? AttributeErrorHow it works.
First, define a class Member with two attributes, name and age:
class Member:
def __init__(self, name, email):
self.name = name
self.email = emailSecond, create a new instance of the Member class:
member = Member('John Doe', '[email protected]')Third, use the getattr() function to get the values of the name and email attribute:
name = getattr(member, 'name')
print(name) # ? John Doe
email = getattr(member, 'email')
print(name) # ? [email protected]It is the same as accessing the attributes directly:
print(member.name) # ? John Doe
print(member.email) # ? [email protected]Finally, attempt to access the non-existing attribute age. It’ll raise an AttributeError exception.
age = getattr(member, 'age')
print(age) # ? AttributeErrorTo avoid the exception, you can pass None as the default value like this:
age = getattr(member, 'age', None)In this case, the age is None.
A practical example of the Python getattr() function #
In practice, you’ll use the getattr() function to call the method of an object dynamically. Note that a method is also an attribute of an object.
Suppose, you need to validate the name and email with the following rules:
nameis required i.e., its length is greater than zero.emailis a valid email address
To do that, you can create a reusable Validation class and use it as follows:
validation = Validation()
data = {'name': '', 'email': 'test'}
rules = {'name': 'required', 'email': 'email'}
errors = validation.validate(data, rules)
print(errors)In this code, the data and rules are dictionaries.
- Each item in the data dictionary has a field name and value.
- Each item in the rules dictionary has the field name and rule, which can be either
requiredoremail.
The code should return the following output:
{
'name': 'The name is required',
'email': 'The email is not a valid email address'
}Let’s develop the Validation class.
First, define a Validation class:
class Validation:
passSecond, declare the error messages (ERRORS) for the required and email rules:
class Validation:
ERRORS = {
'required': 'The {} is required',
'email': 'The {} is not a valid email address'
}Third, define the required() method that returns True if the length of a value is greater than zero and email() method that returns True if a value is a valid email address:
import re
class Validation:
ERRORS = {
'required': 'The {} is required',
'email': 'The {} is not a valid email address'
}
def required(self, value):
return len(value) > 0
def email(self, value):
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
return re.fullmatch(pattern, value)To validate an email address, the email() method uses the fullmatch() function from the regular expression (re) module.
Finally, define the validate() method:
class Validation:
ERRORS = {
'required': 'The {} is required',
'email': 'The {} is not a valid email address'
}
def required(self, value):
return len(value) > 0
def email(self, value):
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
return re.fullmatch(pattern, value)
def validate(self, data, rules):
errors = {}
for field, rule in rules.items():
is_valid_method = getattr(self, rule)
if not is_valid_method(data[field]):
errors[field] = self.ERRORS[rule].format(field)
return errorsIn the validate() method:
- Initialize an errors dictionary to store error messages.
- Iterate the rules from the rules dictionary.
- For each rule, use the
getattr()function to find the method that is corresponding to the rule. For example, thegetattr()returns therequiredmethod for therequiredrule andemailmethod for theemailrule. - Call the method dynamically to validate data. If the method returns
False, add the error message to theerrorsdictionary. - Return the
errors.
Put it all together.
import re
class Validation:
ERRORS = {
'required': 'The {} is required',
'email': 'The {} is not a valid email address'
}
def required(self, value):
return len(value) > 0
def email(self, value):
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
return re.fullmatch(pattern, value)
def validate(self, data, rules):
errors = {}
for field, rule in rules.items():
is_valid_method = getattr(self, rule)
if not is_valid_method(data[field]):
errors[field] = self.ERRORS[rule].format(field)
return errors
validation = Validation()
data = {'name': '', 'email': 'test'}
rules = {'name': 'required', 'email': 'email'}
errors = validation.validate(data, rules)
print(errors)Output:
import re
class Validation:
ERRORS = {
'required': 'The {} is required',
'email': 'The {} is not a valid email address'
}
def required(self, value):
return len(value) > 0
def email(self, value):
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
return re.fullmatch(pattern, value)
def validate(self, data, rules):
errors = {}
for field, rule in rules.items():
is_valid_method = getattr(self, rule)
if not is_valid_method(data[field]):
errors[field] = self.ERRORS[rule].format(field)
return errors
if __name__ == '__main__':
validation = Validation()
data = {'name': '', 'email': 'test'}
rules = {'name': 'required', 'email': 'email'}
errors = validation.validate(data, rules)
print(errors)Output:
{
'name': 'The name is required',
'email': 'The email is not a valid email address'
}If you pass the valid data, the errors will be empty:
# Validation class
if __name__ == '__main__':
validation = Validation()
data = {'name': 'John', 'email': '[email protected]'}
rules = {'name': 'required', 'email': 'email'}
errors = validation.validate(data, rules)
print(errors)Note that this code should contain the Validation class to execute successfully
Output:
{}Note that you can hide the required() and email() method by making them private. In this case, you also need to pass the rule prefixed with an underscore (_) to the getattr() function get the corresponding method:
import re
class Validation:
ERRORS = {
'required': 'The {} is required',
'email': 'The {} is not a valid email address'
}
def _required(self, value):
return len(value) > 0
def _email(self, value):
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
return re.fullmatch(pattern, value)
def validate(self, data, rules):
errors = {}
for field, rule in rules.items():
is_valid_method = getattr(self, f'_{rule}')
if not is_valid_method(data[field]):
errors[field] = self.ERRORS[rule].format(field)
return errorsNotice the following line of code:
is_valid_method = getattr(self, f'_{rule}')Summary #
- Use Python
getattr()function to get a value of a named attribute of an object.
Thank you for your feedback!