向字典添加元素时抛出KeyError异常 - Python3.5.3
Let's break down what's going wrong and how to fix it, starting with the root cause of your KeyError.
First: Understand Why the KeyError Happens
A KeyError almost always means you're trying to access a key that doesn't exist in your dictionary. Looking at your code snippet, I notice two potential issues right away:
- You initialized
decoded_dataas a list ([HexDecode(data[0]), HexDecode(data[1])]), but later you're trying to access it like a dictionary (e.g.,decoded_data.ap...). Lists use index numbers, not named keys—mixing these up will definitely cause errors. - If you did intend
decoded_datato be a dictionary, you might be trying to access a key you never defined, or trying to assign to a key in a way that assumes it already exists.
Practical Solutions to Fix the KeyError
1. Fix the Data Structure Confusion (Most Likely Fix)
If decoded_data is supposed to store metadata like title, artist, etc., it should be a dictionary, not a list. Rewrite your initialization to use key-value pairs:
# Initialize as a dictionary with required fields decoded_data = { "title": HexDecode(data[0]), "artist": HexDecode(data[1]) } # Add optional fields only if data exists if len(data) == 4: decoded_data["album"] = HexDecode(data[2]) decoded_data["track_number"] = HexDecode(data[3]) # Example of another optional field
This way, you're explicitly defining keys and adding new ones safely—assigning to a new key in a dictionary doesn't throw a KeyError, only accessing an undefined one does.
2. Use dict.get() for Safe Key Access
If you need to access a key that might not exist (e.g., optional metadata fields), use the get() method instead of direct bracket access. It returns a default value (like None or a custom placeholder) instead of throwing an error:
# Get album info, or return "Unknown Album" if the key doesn't exist album_name = decoded_data.get("album", "Unknown Album")
3. Check if a Key Exists Before Accessing
If you want to handle missing keys with custom logic, use the in operator to verify the key exists first:
if "album" in decoded_data: print(f"Album: {decoded_data['album']}") else: print("No album metadata available")
4. Initialize Default Keys Upfront
If certain fields should always be present (even if empty), define them when creating the dictionary:
decoded_data = { "title": HexDecode(data[0]), "artist": HexDecode(data[1]), "album": "Unknown", "genre": "Unknown" } # Override defaults only if data is available if len(data) >= 4: decoded_data["album"] = HexDecode(data[2])
Bonus: Improve Your File Parsing Logic
I also noticed a small issue with how you're reading the metadata file. Right now, you only process the data if the final line ends with m>—you might miss earlier complete chunks of metadata. Move the processing logic inside the loop to handle each complete line as it's found:
def metadataScrape(): current_line = "" with open("/tmp/shairport-sync-metadata") as f: for line in f: current_line += line.rstrip('\n') # Cleanly remove newline characters # Check if we've reached the end of a metadata chunk if current_line.endswith("m>"): html_data = html.fromstring(current_line) data = html_data.xpath("//text()") # Initialize dictionary correctly here decoded_data = { "title": HexDecode(data[0]), "artist": HexDecode(data[1]) } if len(data) >= 4: decoded_data["album"] = HexDecode(data[2]) decoded_data["extra"] = HexDecode(data[3]) # Reset for the next chunk of metadata current_line = ""
内容的提问来源于stack exchange,提问作者Srevilo

