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)`来获取它是否存在或者如果没有,则返回默认值。但是,如果您发现自己对大部分属性都使用hasattr
或getattr
,这通常表明您一开始并不想要一个充满属性的对象,而是字典。 (请注意,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# 中快速检查两个数据传输对象是不是具有相同的属性?