python - Remember exceptions raised to handle them later -
tldr: i'd let function run through exceptions, display them @ end , make function raise exception.
i building function (see below) path each value in dictionary, creating dictionary of form "value":"path". have recursive sub-function traversing dictionary doing processing on each node, throwing typeerror when node isn't of supported types, , keyerror when value present.
what i'd do processing on entire dictionary ignoring exceptions , handle them in end, can give path each problematic value. want save flattened dictionary if no exception has been raised.
as stands if wrap call flatten_dict in try...except block first exception raised make changing problematic values tedious. thought using logging, don't know how can make function still raise exception @ end can act accordingly.
i'm wondering if there's way that, or if it's sign should change design ?
thanks
def flatten_dict(dictionary): """ flattens dictionary path each value in dict in dpath format (https://pypi.python.org/pypi/dpath/) returns dict of form "value":"path" param: dictionary: dictionary flattened, should contain each value once, , values should strings >>> reverse_flatten_dict({"k1":{"k2":"v2", "k3":["v3","v4"]}}) {"v2":"k1/k2","v3":"k1/k3/0","v4":"k1/k3/1"} """ def recursive_call(value, path, flattened): """ recursively traverse dictionary add path each string \ value encounters flattened dict """ if isinstance(value, dict): key, val in value.items(): new_path = "{}/{}".format(path,key) recursive_call(val, new_path, flattened) elif isinstance(value, list): i, val in enumerate(value): new_path = "{}/{}".format(path,i) recursive_call(val, new_path, flattened) elif isinstance(value, basestring): if value in flattened: raise keyerror("flatten_dict: value @ {} present more \ once in dictionary".format(path)) flattened[value] = path else: raise typeerror("flatten_dict: value of invalid type @ {},\ value ignored. should dict, list or basestring".format(path)) path = "" flattened = {} if dictionary: recursive_call(dictionary, path, flattened) return flattened
there better ways, simplest way minimum code adjustments create empty list above if dictionary:
, pass recursive function , append messages it. @ end check if there , raise them 1 exception.
example code: (note: i'm using python 3, can't test exact code. parts added should work , rest copied post, should work.)
def flatten_dict(dictionary): """ flattens dictionary path each value in dict in dpath format (https://pypi.python.org/pypi/dpath/) returns dict of form "value":"path" param: dictionary: dictionary flattened, should contain each value once, , values should strings >>> reverse_flatten_dict({"k1":{"k2":"v2", "k3":["v3","v4"]}}) {"v2":"k1/k2","v3":"k1/k3/0","v4":"k1/k3/1"} """ def recursive_call(value, path, flattened, error_list): """ recursively traverse dictionary add path each string \ value encounters flattened dict """ if isinstance(value, dict): key, val in value.items(): new_path = "{}/{}".format(path,key) recursive_call(val, new_path, flattened, error_list) elif isinstance(value, list): i, val in enumerate(value): new_path = "{}/{}".format(path,i) recursive_call(val, new_path, flattened, error_list) elif isinstance(value, basestring): if value in flattened: error_list.append("flatten_dict: value @ {} present more \ once in dictionary".format(path)) flattened[value] = path else: error_list.append("flatten_dict: value of invalid type @ {},\ value ignored. should dict, list or basestring".format(path)) path = "" flattened = {} error_list = [] if dictionary: recursive_call(dictionary, path, flattened, error_list) if error_list: # there @ least 1 error. error_list = ["errors encountered while flattening:"] + error_list raise exception('\n\t'.join(error_list)) return flattened
note don't solution lose exact type of error, not raising error occurs. kind of logging, or flag indicating required behavior (ignore/log/exception) might preferable, depending on application , who'll using it.
Comments
Post a Comment