Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Pythonic way to get either one of two attributes from a Python object

I want to get either one of two attributes from a Python object. If neither of those attributes is present, I want to get a default value.

For instance, I want to get either the number of apples or of oranges in a FruitBasket,
and if neither is present, I want to set n_fruits to 0 (because I am not interested in other fruits).

fruit_basket = FruitBasket(bananas=5)
try:
    n_fruits = getattr(fruit_basket, "apples")
except AttributeError as err:
    n_fruits = getattr(fruit_basket, "oranges")
except AttributeError as err:
    n_fruits = 0

This code breaks if there are neither apples or oranges:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

AttributeError("'FruitBasket' object has no attribute 'oranges'")

The class FruitBasket can hold only one type of fruit. There is no risk that both apples and oranges are present. Even if that was the case, I still would store in n_fruits the first type of fruit (apples, in this case).

I want an elegant Pythonic way to solve this task: I have in mind many possible solutions, but all of them are ugly and convoluted!

By the way, FruitBasket is just an example. I am actually trying to get the centroids from a scikit-learn clusterer. KMeans and MeanShift algorithms store the centroids in the ‘clusters_centers_’ attribute, and GaussianMixture stores it in the ‘means_’ attribute (for my purposes, they are the same). If neither of them is present (in case of other clustering algorithms), I want to set centroids to an empty list.

>Solution :

you code breaks because you need to do add an additional try-except when there is an exception:

fruit_basket = FruitBasket(bananas=5)
try:
    n_fruits = getattr(fruit_basket, "apples")
except AttributeError as err:
    try:
        n_fruits = getattr(fruit_basket, "oranges")
    except AttributeError as err:
        n_fruits = 0

A better way would be to just set a default value to the getattr:

fruit_basket = FruitBasket(bananas=5)
n_fruits = getattr(fruit_basket, "apples", None)
if n_fruits is None:
    n_fruits = getattr(fruit_basket, "oranges", 0)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading