0

我有一个 Python 套接字服务器。在这个套接字服务器中,当新客户端连接并成功验证自己时,它将从数据库中获取其 json 编码信息。当它解码它时,它会转到一个变量。有时在对象中,键不存在。我会得到一个 KeyError 并且整个脚本将关闭。例如:

客户端向服务器发送一个数据包服务器处理它是这样的:

def handleReceiveThisPacket(self, data):
    myInfo = self.info['exampleKey']
    return self.send(myInfo)

如果用户信息中不存在“exampleKey”(嘿,它发生了,就像我为新数据包添加了一个新密钥以处理其他事情并且用户信息尚未更新),整个脚本关闭。我知道我可以很容易地尝试,但我经常在整个脚本中调用键,我认为到处都有一堆尝试和例外看起来很乱,你不觉得吗?有没有一种更简单的方法可以让 Python 发出警告但不会关闭,类似于 PHP 的做法?

此外,客户端是一个单独的类。

4

5 回答 5

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)
于 2013-08-18T18:22:33.070 回答
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作为缺少键的默认值返回,但您可以对其进行自定义。

于 2013-08-18T18:27:53.163 回答
1

首先,PHP 语言做出了许多糟糕的设计决策,这只是其中之一。很高兴 python 以一种很好的方式检测和处理这些问题。我个人总是编写从未产生任何警告的 PHP 代码。一旦收到警告,就很难区分什么是可以接受的,什么是真正的问题。

其次,您可以通过以下几种方式处理问题:

  • 您可以在上层处理这些异常(1 个或 2 个,而不是十几个)
  • 您可以使用defaultdict
  • 您可以使用实用程序功能。

例子:

def getkey(d, k):
  try:
    return d[k]
  except KeyError:
    return ""

请注意,所有这些解决方案都存在严重缺陷,它们会使您的代码变得脆弱。您不会检测到您可以为密钥制作的所有可能的拼写错误。

我认为最明确的方法是用缺失键的值填充您的数据集,这样您就不必进行任何错误处理。

于 2013-08-18T18:21:29.473 回答
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

此外,dicts 有一个.get(key, default=None)方法

于 2013-08-18T18:22:43.383 回答
0

捕捉异常。这个链接解释了 Python 中的异常处理。try... except KeyError...在相关代码周围放一个。

或者,使用字典方法 get。myInfo = self.info.get('exampleKey', default_value)不会引发 KeyError,default_value如果 'exampleKey' 不在 myInfo 中,则会返回。

第三种选择是首先检查键是否在字典中:if 'exampleKey' in self.info: myInfo = self.info['exampleKey'].

于 2013-08-18T18:24:56.330 回答