2

May be it is a common question, but I am new in python!

I am working on some libraries that handle json queries and asked myself if there is some best practice to avoid hard-coding tons of json keys like:


# just an example..
var1 = response.json()["ACRI"]["message"]["title"]
var2 = response.json()["ACRI"]["message"]["content"]
var3 = response.json()["ACRI"]["message"]["meta"]["timestamp"]

when I saw it, it didn't likes me and I created a class with constants like:


class _const:
    class headers:
        X_Auth_Token = "X-Auth-Token"
        X_Username = 'X-Username'
        X_Password = 'X-Password'

    class params:
        ID = "DocumentID"
        Symbols = "Symbols"
        ACRICode = "ACRICode"rketSegmentID"
        entries = "entries"
        depth = "depth"
        date = "date"
        meta = "meta"
        timestamp = "timestamp"
        message = "message"
        # ...

Is that a good practice? Is there something I don't understanding about python compiler?

Thanks

edit: I'm facing performance and/or memory consumption best practices especially

4 Answers 4

2

The performance should be least of your concerns, the maintainability is more important. A good reason to use a symbolic name for a string is that you cannot typo it that easily then, c.f.

KEY_SYMBOLS = "Symbols"

foo[KEY_SYMOBLS]

vs

foo["Symobls"]

An IDE or a linter can find the former typo and highlight it even before running the code, but not so likely the latter one.


When it comes to performance the most performant Python code is the one that does not store strings in variables. Upon compilation the distinct uses of the same string within the same module are merged to reference just one string constant:

>>> 'foo' is 'foo'
True

Still, the point raised in Chepner's answer remains: you need not resolve subdictionaries from the root unnecessarily.

Sign up to request clarification or add additional context in comments.

Comments

1

Your initial strategy follows Zen of Python very well. It is very readable, and anyone who uses Python will understand it right away. Your second example, however, is overly complicated, and difficult to understand.

That said, it is possible to parse json so that it becomes an object with attributes instead of a dict with keys. Your code would then look something like this:

import json
from collections import namedtuple

x = json.loads(response, object_hook=lambda d: namedtuple('X', d.keys())(*d.values()))

var1 = x.ACRI.message.title
var2 = x.ACRI.message.content
var3 = x.ACRI.message.meta.timestamp

Alternatively, define a simple class that takes care of it:

import json

class x(object):
    def __init__(self, j):
        self.__dict__ = json.loads(j)

var1 = x.ACRI.message.title
var2 = x.ACRI.message.content
var3 = x.ACRI.message.meta.timestamp

2 Comments

Your solution is very interesting, I didn't know that and will keep it mind for the future, thank you.. The only one thing makes me some noise, in this particular case, is what if my service provider makes some changes in they API I'll have to modify all source code searching line by line for that json object.
Good point. You may want to consider using constants (see PEP-8), along with getattr(). Something like VAR1_PATH = "ACRI.message.title"; var1 = reduce(getattr, name.split("."), x)
0

Each nested dict is a dict you can store a reference to.

resp = response.json()["ACRI"]["message"]
var1 = resp["title"]
var2 = resp["content"]
var3 = resp["meta"]["timestamp"]

Comments

0

If reading JSON data from a file, use the below code snippet.

with open("config.json") as json_data_file:
    json_text = json_data_file.read()
    json_data = json.loads(json_text, object_hook=lambda d: namedtuple('X', d.keys())(*d.values()))

# Access data using below format 
var1 = json_data.key1.subkey1
var2 = json_data.key2.subkey2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.