Optional Chaining in Python
-
Use
try-except
to Implement Optional Chaining in Python -
Use
getattr
to Implement Optional Chaining in Python -
Use
get(key, value)
to Implement Optional Chaining in Python - Use a Combination of Methods to Implement Optional Chaining in Python
-
Use
getattr
as a Drop-In to Implement Optional Chaining in Python -
Use
glom
to Implement Optional Chaining in Python - Use a Readable Method With Dictionaries and Objects to Implement Optional Chaining in Python
- Conclusion
Python is a programming language used mainly in system scripting, server-side web development, and software development. Also, it consists of simple syntaxes that improve the readability of the code.
Among the features in Python, optional chaining is a safe and concise way of accessing nested object properties. It is the process of calling and querying the properties that may be null or may not be null at the time.
By using optional chaining, we can check internally whether a property in an object is available rather than checking manually.
The optional chaining checks if the property left to the operator is defined or undefined. If the property is not null
, the call succeeds and returns undefined if it is invalid or undefined.
Here, it returns an undefined value instead of reporting an error. Also, this works fine with the function calls even though the method may not exist.
This concept was introduced recently by ECMA International, Technical Committee 39 – ECMAScript, authored by Claude Pache, Gabriel Isenberg, Daniel Rosenwasser, and Dustin Savery.
When writing cleaner code, optional chaining is a nice feature to use.
Below are some methods we can use in implementing optional chaining in Python. We can use these code chunks when building the functions.
Use try-except
to Implement Optional Chaining in Python
The most pythonic way of optional chaining is below.
try:
# statements
except (NameError, AttributeError) as e:
# statements (else)
This method uses the try
command and the except
command. Within try
it contains the statements used in controlling the flow, while except
consists of statements used in handling the errors occurring in passing the instructions to the program.
When a program executes, exceptions can occur. Then they interrupt the program by printing out a message displaying the error and how it happened.
To prevent interruption, we have to catch them. So, handling exceptions like this will aid in getting error-proof code.
Here we are considering two main errors: NameError
and AttributeError
. When we use an undefined variable or a function, NameError
can occur.
If the user tries making an invalid attribute reference, the reference will fail, and AttributeError
can occur. Also, spelling variations will raise as AttributeError
.
As discussed above, this pythonic approach of optional chaining aids in calling the properties, even if they are defined or not, while handling the exceptions.
Use getattr
to Implement Optional Chaining in Python
Instead of the above method, using getattr
is also another method in optional chaining.
getattr(getattr(foo, "bar", None), "baz", None)
Here we use the getattr
function that returns the value of the named attribute from the specified object. The object name should be a string, and if it is a named attribute, it returns the value of that attribute.
But, if the named attribute does not exist, the default value is returned or throws an AttributeError
.
Within this getattr
function, getattr(foo, 'bar', None)
is the object while baz
is the attribute and None
is the default value.
Use get(key, value)
to Implement Optional Chaining in Python
We can use get(key, value)
when it is a dictionary.
{"foo": {"bar": "baz"}}.get("foo", {}).get("bar")
Dictionary is a collection of ordered, changeable, and non-duplicate data values stored as key: value
pairs. Here, 'foo'
, 'bar'
, and 'baz'
are the placeholders we use in Python.
{'foo': {'bar': 'baz'}}
is the dictionary, and with it, we are using two get
functions with a key
and a value
. Here the get
function returns the item’s value with the specified key.
The first get
function consists of a key as 'foo'
and a value of {}
while the second consists only of a key as 'bar'
.
As in the above code snippet, we can adapt the optional chaining concept even when we use a dictionary.
Use a Combination of Methods to Implement Optional Chaining in Python
Below is another method we can follow in optional chaining. It is a combination of methods.
from functools import reduce
def optional_chain(obj, keys):
try:
reduce(getattr, keys.split("."), root)
except AttributeError:
return None
optional_chain(foo, "bar.baz")
At first, we have to import the reduce
module from the functools
that store the intermediate result and return only the final summation. Then the function optional_chain
is defined with two parameters.
After that, we can adapt the first discussed method with try
and the except
controls. Within the try
and except
commands, we have used the getattr
function.
We have described the functionality of getattr
in the second method. Finally, we call the optional_chain
by defining two parameters.
Use getattr
as a Drop-In to Implement Optional Chaining in Python
We can use it as a drop-in without extending the getattr
as above.
from functools import reduce
def rgetattr(obj, attr, *args):
def _getattr(obj, attr):
return getattr(obj, attr, *args)
return reduce(_getattr, attr.split("."), obj)
After importing the module, we defined a function named rgetattr
with three parameters. Then we define the function getattr
as a drop-in.
If the path does not exist, rgetattr
will throw an AttributeError
, and we can specify default instead of None
.
Use glom
to Implement Optional Chaining in Python
Another method we can use in optional chaining is using glom
.
from glom import glom
target = {"a": {"b": {"c": "d"}}}
glom(target, "a.b.c", default=None)
As the first step, we should import the module glom
from the library. Then the target has been defined in the form of a dictionary with a, b,
and c
. Also, d
is the corresponding value of c
.
After that, the function glom
has called with target
and a.b.c
inside it. If any exception occurs, it will print None
as the default value.
Use a Readable Method With Dictionaries and Objects to Implement Optional Chaining in Python
By adapting to the below method, we can make the code more readable when used with dictionaries and objects.
def optional_chain(root, *keys):
result = root
for k in keys:
if isinstance(result, dict):
result = result.get(k, None)
else:
result = getattr(result, k, None)
if result is None:
break
return result
At first, it defined a function named optional_chain
and proceeded with a for
loop and if-else
statements. It used the getattr
function within the flow to obtain the result in the else
part.
We must add keys
after the first argument when using this function.
obj = {"a": {"b": {"c": {"d": 1}}}}
print(optional_chain(obj, "a", "b"), optional_chain(obj, "a", "z"))
Conclusion
Overall, the above methods are the ways we can adapt when we need optional chaining in Python.
We can use the try
and except
approaches and avoid premature optimizations if we know the process and performance problem we solve. Also, we can have a reflection of code by using getattr
.
Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.