I have a Python socket server. In this socket server, when a new client connects and successfully authenticates themselves, it'll grab their json encoded information from the database. When it decodes it, it goes to a variable. Sometimes in the object, a key doesn't exist. I'll get a KeyError and the whole script will shut down. For example:
A client sends a packet to the server The server handles it like this:
def handleReceiveThisPacket(self, data):
myInfo = self.info['exampleKey']
return self.send(myInfo)
If "exampleKey" doesn't exist in the user's info (hey, it happens, like if I added a new key to the info for a new packet to handle something else and the user's info hasn't been updated yet), the whole script shuts down. I know I could easily do try, except but I often call keys throughout the script and I think it would look messy having a bunch of try and excepts everywhere, don't you think? Is there an easier way to just make it so Python gives off a warning about it but doesn't shut down, similar to how PHP does it?
Also, the client is a seperate class.
Use exception handling; to catch the exceptions; they exist for the sole reason that the normal program would be simpler, without a need for constant error checking. Also to get an optional key from dictionary you can use the get
method
def handleReceiveThisPacket(self, data):
# returns None if key not found
myInfo = self.info.get('exampleKey')
# returns 42 if key not found
myInfo = self.info.get('exampleKey', 42)
try:
return self.send(myInfo)
except Exception as e:
print("Oops an exception occurred")
print(e)
You can create your own MyDict
class that wraps the KeyError
and logs out warnings:
import logging
log = logging.getLogger(__name__)
class MyDict(dict):
def __getitem__(self, key):
try:
return super(MyDict, self).__getitem__(key)
except KeyError:
log.warning('Attempted to get value for missing key %s.', str(key))
return None
In [33]: d = MyDict()
In [34]: d['test']
Attempted to get value for missing key test.
Or in short (just for default values):
from collections import defaultdict
c = defaultdict(lambda: None)
c['test']
None
This example returns None
as default value for missing keys, but you can customize it.
First of all, the PHP language made many bad design decisions, this is just one of them. Be happy that python detects and handles these problems in a nice way. I personally always wrote PHP code that never created any warnings. Once you have warnings it's hard to distinguish what's acceptable and what's a real problem.
Second, you can handle the problem several ways:
Example:
def getkey(d, k):
try:
return d[k]
except KeyError:
return ""
Note that all these solution have the serious flaw that they make your code brittle. You won't detect all the possible typos you can make for the keys.
I think the most clear way would be to fill your data set with values for the missing keys, so you don't have to do any error handling.
You may check if something is in a collection using the in
operator:
>>> import json
>>> o = json.loads('{"a": 1}')
>>> "a" in o
True
>>> "b" in o
False
>>> o = dict(a=1)
>>> "a" in o
True
>>> "b" in o
False
>>> o = (1,2,3)
>>> 1 in o
True
>>> 4 in o
False
Also, dict
s have a .get(key, default=None)
method .
Catch the exception. This link explains exception handling in Python. Put a try... except KeyError...
around the relevant code.
Alternatively, use the dictionary method get. myInfo = self.info.get('exampleKey', default_value)
won't raise a KeyError, and will return default_value
if 'exampleKey' isn't in myInfo.
A third option would be to check if the key is in the dictionary first: if 'exampleKey' in self.info: myInfo = self.info['exampleKey']
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.