-2

Everyone. I'm new to python, and I've ran into an issue where I can get the value of a key that contains an underscore. I have the following JSON file that I load from disk. I can access the other values except for the one with an underscore in the key which is cad_id

{
"meta": {
    "summary": "devices are stored here"
},
"devices": [
                {
        "type": "printer device",
        "id": "1",
        "name": "storage_printer",
        "cad_id": "printer"
    },
    {
        "type": "email device",
        "id": "1497041417932",
        "name": "email",
        "cad_id": "tfd04",
    },
    {
        "type": "zone device",
        "id": "1497041431054",
        "name": "Page",
        "cad_id": "page1",
    }
]
}

Here's what I have so far. It seems like the only way to access the key with the underscore is if I test for it and I don't get why I can't just do device['cad_id'] and get the value. I'm not sure what I'm doing wrong, and if someone can tell me what's going on so I can understand it, I would very much appreciate it.

Thank you for your time.

import socket
import json

def load_config():
    filepath = "/var/www/html/fac3-config.json"
    with open(filepath) as file_object:
        config = json.load(file_object)
    return config

def get_device_by_cad_id(cad_id, config):
    devices = config["devices"]
    for device in config["devices"]:        
        #print(device['cad_id']) -- this doesn't work
        print(device['id']) #this works
    # this is the only way that I can access the value of cad_id
    # and I don't understand why
    #if "cad_id" in device:
    #   if device['cad_id'] == cad_id:
    #        return device['id']


config = load_config()
device_id = get_device_by_id("page1", config)
print(device_id)

When I remove the comment where I print the cad_id, I get the following error

Traceback (most recent call last):
File "trigger_hub.py", line 23, in <module>
  device_id = get_device_by_cad_id("page1", config)
File "trigger_hub.py", line 13, in get_device_by_cad_id
  print(device['cad_id']) 
KeyError: 'cad_id'
user252836
  • 49
  • 9
  • 3
    There is no way that `device['cad_id']` doesn't work while `device['id']` works when both of the keys actually present in the dictionary. The problem is somewhere else. – DeepSpace Sep 20 '18 at 15:59
  • 2
    What do you mean by *this doesn't work*? Is there an error? The wrong answer? – pault Sep 20 '18 at 16:00
  • 1
    I get the following error Traceback (most recent call last): File "trigger_hub.py", line 29, in device_id = get_web_button_id("page1", config) File "trigger_hub.py", line 21, in get_web_button_id print(device['cad_id']) KeyError: 'cad_id' – user252836 Sep 20 '18 at 16:02
  • 1
    This has nothing to do with the underscore. `'cad_id'` simply doesn't exist, just like you'd get a `KeyError` for `device['non#existing#key#with#no#underscore']` – DeepSpace Sep 20 '18 at 16:03
  • 1
    The function is named `get_device_by_cad_id`, but the function you're calling is `get_web_button_id`... what's up with that? In the traceback you posted it shows up as `get_web_button_id` as well. I don't believe for a second that the code you posted is a MCVE. – Aran-Fey Sep 20 '18 at 16:04
  • 1
    Possible duplicate of [I'm getting Key error in python](https://stackoverflow.com/questions/10116518/im-getting-key-error-in-python) – pault Sep 20 '18 at 16:45

1 Answers1

2

It may be the case that you don't have a cad_id entry in some records, that's why you may be getting an exception.

You can use dict.get() method, which returns None (or a provided default value) instead of accessing the key by [], as in:

print(device.get('cad_id'))
# or
print(device.get('cad_id', "No cad_id for this record"))

or, alternatively, watch for KeyError exception and handle it as you want in the case there is no cad_id.

Aleph Aleph
  • 5,215
  • 2
  • 13
  • 28