python 是否有速记来检查对象是否具有属性?

con*_*tti 5 python string if-statement conditional-operator python-3.x

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

目前我一直在做:

if jsonobject.what_i_look_for:
  dbstring = jsonobject.what_i_look_for
else:
  dbstring = ""
Run Code Online (Sandbox Code Playgroud)

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

我找到了if-shorthandsthis shorthand 来检查变量是否为空,但两者似乎都不能直接作为字符串工作。我已经print()在交互式 python 3.5.2 shell 中对此进行了测试:

>>> 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
Run Code Online (Sandbox Code Playgroud)

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

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

hee*_*ayl 9

Python化的方式是看出来的NameError,将提出的是没有定义的变量时,异常的名称没有绑定任何对象要精确。

因此,例如:

try:
    foobar
except NameError:
    # Do stuffs
    print('foobar is not defined')
    raise  # raise the original exception again, if you want
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

getattr(obj, attr)
Run Code Online (Sandbox Code Playgroud)

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

obj.foobar
getattr(obj, 'foobar')
Run Code Online (Sandbox Code Playgroud)

即使您可以在缺少 object 属性时添加默认值:

getattr(obj, 'foobar', 'spamegg')
Run Code Online (Sandbox Code Playgroud)

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

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