0

I would like to get an attribute of mongoengine model object but it's missing (how it's often in mongo):

unit.city gives me AttributeError

unit.get('city') says that 'Unit' object has no attribute 'get' and I can't find any appropriate method by dir(unit).

So I have to use standard python statement:

city = unit.city if 'city' in unit else None

That is a bit complex for just a get operation, because I have many transformations of that kind.

And so I wonder if there is any universal method for getting attribute value or some default value (if attribute doesn't exist) — such as get for dict type:

city = unit.get('city') # None
# or
city = unit.get('city', 'Moscow') # 'Moscow'

I would define my own function get but I'm interested if there is any in standard libraries. And yet, from operation import getitem doesn't able to do that.

I use python 2, by the way.

egvo
  • 1,493
  • 18
  • 26

2 Answers2

3

In general python, there are two common patterns. A mix of hasattr + getattr or wrapping the whole thing in try / except

city = getattr(unit,'city','Moscow')

Other approach is

try:
    city = unit.city
except AttributeError:
    city = None

The second is argubly more pythonic. However when you are dealing with databases. It's better to use an ORM and avoid this sort of thing all together.

e4c5
  • 52,766
  • 11
  • 101
  • 134
  • Missed one single quote in the first approach. – yuwang Jun 09 '17 at 08:01
  • The second is certainly not "more pythonic" since the whole point of allowing a `default` argument to `getattr()` is to avoid the (potentially costly) exception handler. – bruno desthuilliers Jun 09 '17 at 08:36
  • @brunodesthuilliers secondly is definitely more pythonic. https://docs.python.org/2/glossary.html pythonic is not about what is more peformant and what is not. – e4c5 Jun 09 '17 at 08:45
  • Yes I know about the EAFP vs LBYL thing - but here by using `getattr()` with a default argument, we don't LBYL, we just make proper use of the language's features. It's just like using `dict.get()` vs catching a `KeyError`. – bruno desthuilliers Jun 09 '17 at 08:56
  • I think this is getting to be a matter of opinon. Let's agree to disagree – e4c5 Jun 09 '17 at 08:59
  • @e4c5 Thanks, that what I've been looking for. – egvo Jun 09 '17 at 09:14
1

There is getattr(object, name[, default]):

city = getattr(unit, 'city', 'Moscow')
Dan D.
  • 73,243
  • 15
  • 104
  • 123