Python检查一个或多个值是否为None并知道哪些值是

时间:2018-02-12 17:54:06

标签: python algorithm firebase-realtime-database

我有一个带有Firebase数据库后端的Python应用程序。

当我从数据库中检索数据时,我想检查这些值是否存在 可用(如果没有,这意味着数据库以某种方式被破坏,因为缺少强制性字段)

我目前的实施如下:

self.foo = myDbRef.get('foo')
self.bar =  myDbRef.get('bar')
self.bip =  myDbRef.get('bip')
self.plop = myDbRef.get('plop')

if self.foo is None or self.bar is None or self.bip is None or self.plop is None:
    self.isValid = False
    return ErrorCode.CORRUPTED_DATABASE

这很好,很紧凑,但有一个主要问题:我将获得数据库已损坏的信息, 但不是缺少什么领域(可能只是其中之一,或更多,或全部!)

惯用法应该是

if self.foo is None:
    self.isValid = False
    return ErrorCode.CORRUPTED_DATABASE, "FOO IS MISSING" # could be a string, an enum value, whatever, I have the information

if self.bar is None:
    self.isValid = False
    return ErrorCode.CORRUPTED_DATABASE, "BAR IS MISSING"

if self.bip is None:
    self.isValid = False
    return ErrorCode.CORRUPTED_DATABASE, "BIP IS MISSING"

但这不是很漂亮,没有分解(我所有'来自db'函数的init都使用相同的模式...我不想繁殖我的 对于这种情况,行数为10)。

这不是一个'100%python'的问题,但是我希望这句话能让我像老板一样处理这个问题(它的蟒蛇:通常会这样!)

4 个答案:

答案 0 :(得分:1)

您可以将检查提取到生成器中,并将标记和return语句保留在外面。

def invalid_fields():
    if self.foo is None: yield "FOO"
    if self.bar is None: yield "BAR"
    if self.bip is None: yield "BIP"

invalid = list(invalid_fields())
if invalid:
    self.isValid = False
    return ErrorCode.CORRUPTED_DATABASE, "MISSING {}".format(", ".join(invalid))

如果有多个字段,则可以告诉您所有缺少的字段。

答案 1 :(得分:0)

我创建了一个类来包含一些我无法访问的功能。我还将ErrorCode作为一个字符串作为hack,因为我的工具中没有定义它,我不确定你希望如何在ErrorCode旁边返回None名称。

构建dict个名称和值,检查dict是否包含None值,如果是,则返回哪些键:

myDbRef = {'foo' : None,
            'bar': 1,
            'bip': 2,
            'plop': 3}
class Foo():

    def __init__(self):

        self.foo = myDbRef.get('foo')
        self.bar =  myDbRef.get('bar')
        self.bip =  myDbRef.get('bip')
        self.plop = myDbRef.get('plop')


    def check(self):

        temp_dict = {}

        for key in ['foo','bar','bip','plop']:
            temp_dict[key] = myDbRef.get(key)

        vals = {k:v for k,v in temp_dict.items() if v is None}
        if vals:
            self.isValid = False
            return ("ErrorCode.CORRUPTED_DATABASE", [k for k in vals.keys()])


f = Foo()
print(f.check())

结果:('ErrorCode.CORRUPTED_DATABASE', ['foo'])

答案 2 :(得分:0)

使用函数和循环:

def checknone(**things_with_names):
    for name, thing in things_with_names.items():
        if thing is None:
            return ErrorCode.CORRUPTED_DATABASE, name + " IS MISSING"
    return True

并按原样使用:

result = checknone(foo=self.foo, bar=self.bar, bip=self.bip, plop=self.plop)
if result is not True:
    self.isValid = False
    return result

为获得最大收益,请将其作为一个类的方法,将Mixin放入所有使用它的类中。这样它也可以设置isValid

答案 3 :(得分:0)

您可以动态创建和搜索实例属性,如下所示:

git reset HEAD^ --hard