python是不是有检查对象是不是具有属性的简写? [复制]

Posted

技术标签:

【中文标题】python是不是有检查对象是不是具有属性的简写? [复制]【英文标题】:Does python have a shorthand to check if an object has an attribute? [duplicate]python是否有检查对象是否具有属性的简写? [复制] 【发布时间】:2019-01-23 15:59:20 【问题描述】:

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

目前我一直在做:

if jsonobject.what_i_look_for:
  dbstring = jsonobject.what_i_look_for
else:
  dbstring = ""

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

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

>>> 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 的 JSON API。我使用python-telegram-bot 作为库,this 是一个示例对象。

【问题讨论】:

jsonobject.what_i_look_for 是一个属性,而不是一个变量。您的问题是关于变量还是关于属性?此外,if jsonobject.what_i_look_for: 检查what_i_look_for_attribute 是否设置为真值;它检查该属性是否存在。那么,再次,您的问题是什么? 变量在 Python 中并不存在。有一些名称被分配了对象。 hasattr 可能是您想要的,尽管ask forgiveness not permission 可能更好 是的,属性和变量是不同的。 如果你正在寻找一个对象的属性,那么你可以使用hasattr(obj, name)来查看它是否存在,或者getattr(obj, name, default)`来获取它是否存在或者如果没有,则返回默认值。但是,如果您发现自己对大部分属性都使用hasattrgetattr,这通常表明您一开始并不想要一个充满属性的对象,而是字典。 (请注意,stdlib json 模块使用字典。) 【参考方案1】:

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

所以,例如:

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

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 是要走的路:

getattr(obj, attr)

例如下面两个是等价的:

obj.foobar
getattr(obj, 'foobar')

即使在缺少对象属性时也可以添加默认值:

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

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

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

【讨论】:

有没有办法我可以为此编写一个函数或任何东西?我的目标是获得一个简短而干净的代码,对于我需要检查的每个变量都有一个 try 块并不能完全实现这一点。 @confetti 名称驻留在命名空间中,例如本地名称位于 locals() 命名空间中,全局名称位于 globals() 命名空间中。您可以定义一个以命名空间为参数的函数来检查是否存在。 except NameError 对我来说是相当主要的代码味道,除非你可能会遇到一些非常神秘的元编程黑魔法。无论如何,阅读操作我不清楚这是否是他们所需要的,因为他们正在谈论对象的属性。 @confetti 为什么您发现自己处于不知道名称是否在范围内的情况?这似乎与您的问题根本无关,这是关于对象的属性,而不是是否定义了变量...... @juanpa.arrivillaga 我已经编辑了我的 OP。我想我一开始的措辞是错误的。我添加了一个我正在使用的确切对象的示例。

以上是关于python是不是有检查对象是不是具有属性的简写? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何检查包含另一个对象数组的对象数组是不是具有属性

检查对象是不是具有属性[重复]

如何在 C# 中快速检查两个数据传输对象是不是具有相同的属性?

检查自定义对象列表是不是与 Java 8 中的属性具有相同的值

如何检查对象是不是具有某些方法/属性?

如何检查对象是不是在 JavaScript 中具有特定属性?