Roy Smith wrote: > In article <54521c8f$0$12982$c3e8da3$54964...@news.astraweb.com>, > Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info> wrote: > >> Anton wrote: >> >> > Let's say I have an incoming list of values *l*. Every element of *l* >> > can be one of the following options: >> > 1) an integer value >> > 2) a string in form of '<int_value>', e.g. '7' >> > 3) a string with a json serialization of an integer value, e.g. '"7"' >> > 4) something else that should be ignored >> > >> > I need to transform this list into another list with values from >> > options 1)-3) coerced to int. The code below should do this. >> >> I don't particularly like either version. I prefer this: >> >> def load_int(obj): >> if isinstance(obj, int): >> # Case 1), an int, e.g. 7 >> return obj >> elif isinstance(obj, str): >> # Case 2) and 3), a str or JSON serialised int. >> # E.g. '7' or '"7"'. >> try: >> return int(obj) >> except ValueError: >> return int(json.loads(obj)) >> raise TypeError('require int or str, got %s' % type(obj).__name__) > > Depending on how strictly you're trying to do input validation, the > int(json.loads(obj)) may not be what you want. It allows well-formed > json encoding floats, for example.
Really? py> int(json.loads(json.dumps(23.5))) 23 Damn! You're right. Back to Plan A: elif isinstance(obj, str): try: return int(obj) except ValueError: if obj and obj.startswith('"') and obj.endswith('"'): return int(obj[1:-1]) raise But of course even the int() function itself may be a little more flexible than we might want: py> int(' 1 ') 1 So I guess the lessons are: * before writing code, you need to decide what the code is meant to do; * and that includes what input must be rejected, not just what input must be accepted. > And, of course, since > >>>> isinstance(True, int) > True > > this code accepts booleans. Oh, but wait, that's by design :-) Naturally :-) If you wanted to avoid it, that's easy, add a clause: if isinstance(obj, bool): raise TypeError at the start of the function. -- Steven -- https://mail.python.org/mailman/listinfo/python-list