Bruce
Bruce

Reputation: 1380

String checking on multiple types

I have a variable containing a string (extracted from a XML feed). The string value can be of type integer, date or string. I need to convert it from string to given data type. I am doing it this way but it is a little bit ugly so I am asking if there is a better technique. If I would checking for more types, I will end with very nested try - except blocks.

def normalize_availability(self, value):
    """
    Normalize the availability date.
    """
    try:
        val = int(value)
    except ValueError:
        try:
            val = datetime.datetime.strptime(value, '%Y-%m-%d')
        except (ValueError, TypeError):
            # Here could be another try - except block if more types needed
            val = value

Thanks!

Upvotes: 0

Views: 106

Answers (3)

kindall
kindall

Reputation: 184200

Use a handy helper function.

def tryconvert(value, default, *types):
    """Converts value to one of the given types.  The first type that succeeds is
       used, so the types should be specified from most-picky to least-picky (e.g.
       int before float).  The default is returned if all types fail to convert
       the value.  The types needn't actually be types (any callable that takes a
       single argument and returns a value will work)."""
    value = value.strip()
    for t in types:
        try:
            return t(value)
        except (ValueError, TypeError):
            pass
    return default

Then write a function for parsing the date/time:

def parsedatetime(value, format="%Y-%m-%d")
    return datetime.datetime.striptime(value, format)

Now put 'em together:

value = tryconvert(value, None, parsedatetime, int)

Upvotes: 5

wst
wst

Reputation: 1

def normalize_availability(value):
    """
    Normalize the availability date.
    """
    val = value
    try:
        val = datetime.datetime.strptime(value, '%Y-%m-%d')
    except (ValueError):
        if value.strip(" -+").isdigit():
            val = int(value)

    return val

Upvotes: 0

cmd
cmd

Reputation: 5830

The right way would be to know from the xml what type each should be. This would prevent things that happen to be numeric strings from ending up as an int, etc. But assuming that isn't possible.

for int type I prefer

if value.isdigit():
    val = int(value)

for the date, the only other way I can think of would be splitting it and looking at the parts, which would be messier then just letting the strptime raise an exception.

Upvotes: 0

Related Questions