我有一个Python套接字服务器。在此套接字服务器中,当新客户端连接并成功验证自身时,它将从数据库中获取其json编码信息。当它解码它时,它会转到一个变量。有时在对象中,密钥不存在。我将得到一个KeyError,整个脚本将关闭。例如:
客户端将数据包发送到服务器 服务器像这样处理它:
def handleReceiveThisPacket(self, data):
myInfo = self.info['exampleKey']
return self.send(myInfo)
如果用户的信息中不存在“exampleKey”(嘿,它会发生,就像我为新数据包的信息添加新密钥以处理其他内容并且用户的信息尚未更新) ,整个脚本关闭。我知道我可以很容易地尝试,除了我经常在整个脚本中调用键,我认为在各处尝试和排除它会看起来很乱,你不觉得吗?是否有一种更简单的方法来实现它,以便Python发出警告但不关闭,类似于PHP的工作方式?
此外,客户端是一个单独的类。
答案 0 :(得分:5)
使用异常处理;抓住例外;它们存在的唯一原因是普通程序更简单,无需进行持续的错误检查。另外,要从字典中获取可选键,您可以使用get
方法
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)
答案 1 :(得分:2)
您可以创建自己的MyDict
类来包装KeyError
并注销警告:
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.
或简而言之(仅用于默认值):
from collections import defaultdict
c = defaultdict(lambda: None)
c['test']
None
此示例返回None
作为缺失键的默认值,但您可以自定义它。
答案 2 :(得分:1)
首先,PHP语言做出了许多糟糕的设计决策,这只是其中之一。很高兴python以一种很好的方式检测并处理这些问题。我个人总是编写从未创建任何警告的PHP代码。一旦你收到警告,很难区分什么是可以接受的,什么是真正的问题。
其次,您可以通过以下几种方式解决问题:
示例:
def getkey(d, k):
try:
return d[k]
except KeyError:
return ""
请注意,所有这些解决方案都存在严重缺陷,导致代码变脆。您不会检测到您可以为密钥设置的所有错误。
我认为最明确的方法是使用缺失键的值填充您的数据集,这样您就不必执行任何错误处理。< / p>
答案 3 :(得分:1)
您可以使用in
运算符检查集合中是否有某些内容:
>>> 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
此外,dict
还有.get(key, default=None)
method。
答案 4 :(得分:0)
抓住异常。 This链接解释了Python中的异常处理。在相关代码周围添加try... except KeyError...
。
或者,使用字典方法get。 myInfo = self.info.get('exampleKey', default_value)
不会引发KeyError,如果'exampleKey'不在myInfo中,则会返回default_value
。
第三种选择是先检查密钥是否在字典中:if 'exampleKey' in self.info: myInfo = self.info['exampleKey']
。