Skip to main content
added 51 characters in body; edited tags; edited title
Source Link
200_success
  • 144.2k
  • 22
  • 188
  • 473

How many actions to 'try' before calling 'except'? Dict lookup with type conversion and fallback

Given the following working code:

def get(self, key, default=None, type=None):
    """Return the default value if the requested data doesn't exist.
    If `type` is provided and is a callable it should convert the value,
    return it or raise a :exc:`ValueError` if that is not possible.  In
    this case the function will return the default as if the value was not
    found:

    >>> d = TypeConversionDict(foo='42', bar='blub')
    >>> d.get('foo', type=int)
    42
    >>> d.get('bar', -1, type=int)
    -1

    :param key: The key to be looked up.
    :param default: The default value to be returned if the key can't
                    be looked up.  If not further specified `None` is
                    returned.
    :param type: A callable that is used to cast the value in the
                 :class:`MultiDict`.  If a :exc:`ValueError` is raised
                 by this callable the default value is returned.
    """
    try:
        rv = self[key]
        if type is not None:
            rv = type(rv)
    except (KeyError, ValueError):
        rv = default
    return rv

While it is clear that if we attempt to get a the value of a non-existent key, we will get a KeyError, it is not immediately discernible what will lead to a ValueError. It's only when we pass a string that does not contain an int do we see that this is where type() fails, and a ValueError is caught and handled.

How many actions to try before calling except? Should it not be written more explicitly and with more granularity thus:

try:
    rv = self[key]
except KeyError:
    rv = default
try:
    if type is not None:
        rv = type(rv)
except ValueError:
    rv = default
return rv

How many actions to 'try' before calling 'except'?

Given the following working code:

def get(self, key, default=None, type=None):
    """Return the default value if the requested data doesn't exist.
    If `type` is provided and is a callable it should convert the value,
    return it or raise a :exc:`ValueError` if that is not possible.  In
    this case the function will return the default as if the value was not
    found:

    >>> d = TypeConversionDict(foo='42', bar='blub')
    >>> d.get('foo', type=int)
    42
    >>> d.get('bar', -1, type=int)
    -1

    :param key: The key to be looked up.
    :param default: The default value to be returned if the key can't
                    be looked up.  If not further specified `None` is
                    returned.
    :param type: A callable that is used to cast the value in the
                 :class:`MultiDict`.  If a :exc:`ValueError` is raised
                 by this callable the default value is returned.
    """
    try:
        rv = self[key]
        if type is not None:
            rv = type(rv)
    except (KeyError, ValueError):
        rv = default
    return rv

While it is clear that if we attempt to get a the value of a non-existent key, we will get a KeyError, it is not immediately discernible what will lead to a ValueError. It's only when we pass a string that does not contain an int do we see that this is where type() fails, and a ValueError is caught and handled.

Should it not be written more explicitly and with more granularity thus:

try:
    rv = self[key]
except KeyError:
    rv = default
try:
    if type is not None:
        rv = type(rv)
except ValueError:
    rv = default
return rv

Dict lookup with type conversion and fallback

Given the following working code:

def get(self, key, default=None, type=None):
    """Return the default value if the requested data doesn't exist.
    If `type` is provided and is a callable it should convert the value,
    return it or raise a :exc:`ValueError` if that is not possible.  In
    this case the function will return the default as if the value was not
    found:

    >>> d = TypeConversionDict(foo='42', bar='blub')
    >>> d.get('foo', type=int)
    42
    >>> d.get('bar', -1, type=int)
    -1

    :param key: The key to be looked up.
    :param default: The default value to be returned if the key can't
                    be looked up.  If not further specified `None` is
                    returned.
    :param type: A callable that is used to cast the value in the
                 :class:`MultiDict`.  If a :exc:`ValueError` is raised
                 by this callable the default value is returned.
    """
    try:
        rv = self[key]
        if type is not None:
            rv = type(rv)
    except (KeyError, ValueError):
        rv = default
    return rv

While it is clear that if we attempt to get a the value of a non-existent key, we will get a KeyError, it is not immediately discernible what will lead to a ValueError. It's only when we pass a string that does not contain an int do we see that this is where type() fails, and a ValueError is caught and handled.

How many actions to try before calling except? Should it not be written more explicitly and with more granularity thus:

try:
    rv = self[key]
except KeyError:
    rv = default
try:
    if type is not None:
        rv = type(rv)
except ValueError:
    rv = default
return rv
Source Link
Pyderman
  • 215
  • 1
  • 7

How many actions to 'try' before calling 'except'?

Given the following working code:

def get(self, key, default=None, type=None):
    """Return the default value if the requested data doesn't exist.
    If `type` is provided and is a callable it should convert the value,
    return it or raise a :exc:`ValueError` if that is not possible.  In
    this case the function will return the default as if the value was not
    found:

    >>> d = TypeConversionDict(foo='42', bar='blub')
    >>> d.get('foo', type=int)
    42
    >>> d.get('bar', -1, type=int)
    -1

    :param key: The key to be looked up.
    :param default: The default value to be returned if the key can't
                    be looked up.  If not further specified `None` is
                    returned.
    :param type: A callable that is used to cast the value in the
                 :class:`MultiDict`.  If a :exc:`ValueError` is raised
                 by this callable the default value is returned.
    """
    try:
        rv = self[key]
        if type is not None:
            rv = type(rv)
    except (KeyError, ValueError):
        rv = default
    return rv

While it is clear that if we attempt to get a the value of a non-existent key, we will get a KeyError, it is not immediately discernible what will lead to a ValueError. It's only when we pass a string that does not contain an int do we see that this is where type() fails, and a ValueError is caught and handled.

Should it not be written more explicitly and with more granularity thus:

try:
    rv = self[key]
except KeyError:
    rv = default
try:
    if type is not None:
        rv = type(rv)
except ValueError:
    rv = default
return rv