取消 Python 中的 "None" 个对象

Unpickling "None" object in Python

我正在使用 redis 来尝试保存请求的会话对象。基于 how to store a complex object in redis (using redis-py),我有:

def get_object_redis(key,r):
    saved = r.get(key)
    obj = pickle.loads(saved)
    return obj

redis = Redis()
s = get_object_redis('saved',redis)

我遇到过没有保存的会话并且 'saved' 计算为 None 的情况。在这种情况下,我得到:

TypeError: must be string or buffer, not None

处理此问题的最佳方法是什么?

有几种处理方法。这是他们的共同点:

def get_object_redis(key,r):
    saved = r.get(key)
    if saved is None:
        # maybe add code here
        return ... # return something you expect
    obj = pickle.loads(saved)
    return obj

如果找不到密钥,您需要明确您的期望。

版本 1
一个例子就是你 return None:

def get_object_redis(key,r):
    saved = r.get(key)
    if saved is None:
        return None
    obj = pickle.loads(saved)
    return obj

redis = Redis()
s = get_object_redis('saved',redis)

s 就是 None。这可能很糟糕,因为您需要在某个地方处理它,而您不知道它是未找到还是已找到并且真的 None.

版本 2
您创建一个对象,也许基于密钥,您可以构造该对象,因为您知道密钥背后的内容。

class KeyWasNotFound(object):
    # just an example class
    # maybe you have something useful in mind
    def __init__(self, key):
        self.key = key

def get_object_redis(key,r):
    saved = r.get(key)
    if saved is None:
        return KeyWasNotFound(key)
    obj = pickle.loads(saved)
    return obj

通常,如果身份很重要,您会在创建对象后将其存储到 return 相同的对象作为键。

版本 3
TypeError 是一个非常普遍的错误。您可以创建自己的错误 class。这对我来说是首选方式,因为我不喜欢版本 1,也不知道哪个对象对 return 有用。

class NoRedisObjectFoundForKey(KeyError):
    pass

def get_object_redis(key,r):
    saved = r.get(key)
    if saved is None:
        raise NoRedisObjectFoundForKey(key)
    obj = pickle.loads(saved)
    return obj