Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python .get() and None

Tags:

python

I love python one liners:

u = payload.get("actor", {}).get("username", "")

Problem I face is, I have no control over what 'payload' contains, other than knowing it is a dictionary. So, if 'payload' does not have "actor", or it does and actor does or doesn't have "username", this one-liner is fine.

Problem of course arises when payload DOES have actor, but actor is not a dictionary.

Is there as pretty a way to do this comprehensively as a one liner, and consider the possibility that 'actor' may not be a dictionary?

Of course I can check the type using 'isinstance', but that's not as nice.

I'm not requiring a one liner per se, just asking for the most efficient way to ensure 'u' gets populated, without exception, and without prior knowledge of what exactly is in 'payload'.

like image 874
hikaru Avatar asked Dec 18 '15 14:12

hikaru


People also ask

What does -> None do in Python?

The None keyword is used to define a null variable or an object. In Python, None keyword is an object, and it is a data type of the class NoneType . We can assign None to any variable, but you can not create other NoneType objects. Note: All variables that are assigned None point to the same object.

Is 0 and None the same in Python?

Definition and UsageNone is not the same as 0, False, or an empty string. None is a data type of its own (NoneType) and only None can be None.

What is difference between None and in Python?

You want to use None to imply that there is no valid object. You want to use [] to imply an object that is of type list and has no elements.

What is Python None type?

NoneType in Python is a data type that simply shows that an object has no value/has a value of None . You can assign the value of None to a variable but there are also methods that return None .


2 Answers

Using EAFP

As xnx suggested, you can take advantage of the following python paradigm:

Easier to ask for forgiveness than permission

you can use it on KeyErrors as well:

try:
    u = payload["actor"]["username"]
except (AttributeError, KeyError):
    u = ""

Using a wrapper with forgiving indexing

Sometimes it would be nice to have something like null-conditional operators in Python. With some helper class this can be compressed into a one-liner expression:

class Forgive:
  def __init__(self, value = None):
    self.value = value
  def __getitem__(self, name):
    if self.value is None:
      return Forgive()
    try:
      return Forgive(self.value.__getitem__(name))
    except (KeyError, AttributeError):
      return Forgive()
  def get(self, default = None):
    return default if self.value is None else self.value

data = {'actor':{'username': 'Joe'}}
print(Forgive(data)['actor']['username'].get('default1'))
print(Forgive(data)['actor']['address'].get('default2'))

ps: one could redefine __getattr__ as well besides __getitem__, so you could even write Forgive(data)['actor'].username.get('default1').

like image 100
Tamas Hegedus Avatar answered Nov 03 '22 03:11

Tamas Hegedus


Why not use an Exception:

try:
    u = payload.get("actor", {}).get("username", "")
except AttributeError:
    u = ""
like image 27
xnx Avatar answered Nov 03 '22 01:11

xnx