关于字符串:python是否有一个窍门来检查对象是否有属性?

Does python have a shorthand to check if an object has an attribute?

本问题已经有最佳答案,请猛点这里访问。

背景是我从JSONAPI获取数据,其中有许多字段是可选的,我需要数据库中的大部分字段。当某个特定字段不可用时,我希望将一个空字符串(""写入数据库。

目前我一直在做:

1
2
3
4
if jsonobject.what_i_look_for:
  dbstring = jsonobject.what_i_look_for
else:
  dbstring =""

然后将dbstring插入数据库。不过,我现在得到了更多的这些字段,我想要一个更干净的代码,而不是一个包含大约80%if语句的函数。

我已经找到了如果速记和这个速记来检查变量是否为空,但两者似乎都不能直接作为字符串工作。我在交互式python 3.5.2 shell中使用print()测试了这一点:

1
2
3
4
5
6
7
8
9
>>> print(testvar or"")
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
NameError: name 'testvar' is not defined

>>> print(testvar if testvar else"")
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
NameError: name 'testvar' is not defined

这:echo (isset($testvar) ? $testvar :"");是我所寻找的PHP等价物。

编辑:因为它似乎是相关的:我试图处理的对象来自于Telegram的JSONAPI。我使用python-telegram-bot作为库,这是一个示例对象。


pythonic方法是寻找NameError异常,当变量未定义时会引发异常,名称未绑定到任何要精确的对象。

例如:

1
2
3
4
5
6
try:
    foobar
except NameError:
    # Do stuffs
    print('foobar is not defined')
    raise  # raise the original exception again, if you want

名称位于命名空间中,例如本地名称位于locals()命名空间(dict命名空间),全局名称位于globals()命名空间(dict命名空间)。您可以定义一个函数,将名称字符串和命名空间作为参数来检查是否存在,这里有一个提示,将命名空间作为dict传递,并捕获KeyError

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
In [1213]: def is_defined(name, namespace):
      ...:     try:
      ...:         namespace[name]
      ...:     except KeyError:
      ...:         return False
      ...:     return True
      ...:

In [1214]: is_defined('spamegg', globals())
Out[1214]: False

In [1215]: spamegg = 10

In [1216]: is_defined('spamegg', globals())
Out[1216]: True

另一方面,如果要获取对象的属性字符串的值,则可以使用getattr

1
getattr(obj, attr)

例如,以下两个是等效的:

1
2
obj.foobar
getattr(obj, 'foobar')

甚至可以在缺少对象属性时添加默认值:

1
getattr(obj, 'foobar', 'spamegg')

以上将输出值obj.foobar,如果缺少foobar,将输出spamegg

您可能还对返回True/False进行属性存在性检查的hasattr感兴趣,而不需要手动处理AttributeError