Storing dictionary locations as a string and using eval - alternatives?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu Aug 20 06:43:55 CEST 2015


On Thursday 20 August 2015 13:59, Victor Hooi wrote:

> Hi,
> 
> I have a textfile with a bunch of JSON objects, one per line.
> 
> I'm looking at parsing each of these, and extract some metrics from each
> line.
> 
> I have a dict called "metrics_to_extract", containing the metrics I'm
> looking at extracting. In this, I store a name used to identify the
> metric, along with the location in the parsed JSON object.
> 
> Below is my code:
> 
>>>>>>>>>>>>>>>>>>>>>>>>
> metrics_to_extract = {
>     'current_connections': "server_status_json['connections']['current']",
>     'resident_memory': "server_status_json['mem']['resident']"
> }
> 
> 
> def add_point(name, value, timestamp, tags):
>     return {
>         "measurement": name,
>         "tags": tags,
>         # "time": timestamp.isoformat(),
>         "time": timestamp,
>         "fields": {
>             "value": float(value)
>         }
>     }

The function name is misleading and you should consider changing it. 
Misleading names make code harder to understand and maintain. The function 
doesn't "add point" at all, that implies that it should modify some data 
structure by adding (appending?) a point to it. Instead, it generates a dict 
containing (I presume) a data point.

But moving on...

Change metrics_to_extract above to this:

metrics_to_extract = {
    'current_connections': ['connections', 'current'],
    'resident_memory': ['mem', 'resident'],
    }

add this helper function:

def get_nested_items(obj, *names):
    """Return obj[name][name2] ... [nameN] for any list of names."""
    for name in names:
        obj = obj[name]
    return obj


and modify the code below as shown:


> with open(input_file, 'r') as f:
>     json_points = []
>     for line in f:
>         if line.startswith("{"):
[...]
>             for key, value in metrics_to_extract.items():
>                 json_points.append(add_point(key, eval(value), timestamp,
>                 tags))

            for key, names in metrics_to_extract.items():
                value = get_nested_items(server_status_json, *names)
                point = add_point(key, value, timestamp, tags)
                json_points.append(point)




-- 
Steven



More information about the Python-list mailing list