0

Is it possible to convert the following into a lambda expression?

def default(o):
    if isinstance(o, (datetime.date, datetime.datetime)):
        return o.isoformat()

json.dumps(raw, default=default)

Something like:

json.dumps(raw, default=lambda o: o.isoformat() if isinstance(o, (datetime.date, datetime.datetime))...? )
David542
  • 104,438
  • 178
  • 489
  • 842

3 Answers3

1

You need an else to finish the conditional expression. Since a function returns None by default if it doesn't execute an explicit return statement, that's what your else should be.

json.dumps(raw, default=lambda o: o.isoformat() if isinstance(o, (datetime.date, datetime.datetime)) else None)
Barmar
  • 741,623
  • 53
  • 500
  • 612
1

Just as you described, you can also add else statement there to handle output that returns false from the if check (splitted lines to get some readability, python might like more the oneliner).

json.dumps(raw, default=lambda o: o.isoformat() 
                                  if isinstance(o, (datetime.date, datetime.datetime)) 
                                  else None)
paloman
  • 160
  • 9
0

Should be able to with:

default = lambda o: o.isoformat() if isinstance(
    o, (datetime.date, datetime.datetime)) else o.__dict__

You can use None as well for your return, but see what happens when you do that if you were to include a custom object that JSONEncoder doesn't pick up on:

default = lambda o: o.isoformat() if isinstance(
    o, (datetime.date, datetime.datetime)) else None


class A:
    def __init__(self, x):
        self.x = x


a = A(10)
d = {'date': datetime.datetime.now(), 'myobject': a}
f = json.dumps(z, default=default)

>>> json.loads(f)
{'date': '2020-08-13T22:35:46.872594', 'myobject': None}

Same thing but with o.__dict__:

>>> json.loads(f)
{'date': '2020-08-13T22:36:22.512864', 'myobject': {'x': 10}}

Although with a custom object ideally you should have __repr__ set up well and then you can even recreate your object.

Algebra8
  • 1,115
  • 1
  • 10
  • 23
  • why `o.__dict__` instead of `None` or `o` or something else? – David542 Aug 14 '20 at 05:11
  • I just think it is a better habit/usage than `None` because say you have a dict with a custom object in there as well. Try encoding then decoding that - you will get `None` for the custom object. Returning `o.__dict__` can have issues though, read [here](https://stackoverflow.com/questions/3768895/how-to-make-a-class-json-serializable) for more info. – Algebra8 Aug 14 '20 at 05:34
  • @Algebra8 my inclination would be to throw an error, and explicitly deal with each possible type you may have. – juanpa.arrivillaga Aug 14 '20 at 07:15
  • @juanpa.arrivillaga you definitely could do that but then you would have to run the encoding again every time you run into that error, instead of just doing it in one shot. Also, this is not a hack; look into overriding `JSONEncoder`. – Algebra8 Aug 14 '20 at 14:26