7 回答
TA贡献1841条经验 获得超3个赞
如果它是一本字典,你可以使用get(keyname, value)
{'foo': {'bar': 'baz'}}.get('foo', {}).get('bar')
TA贡献1883条经验 获得超3个赞
最Pythonic的方式是:
try:
# do something
...
except (NameError, AttributeError) as e:
# do something else
...
TA贡献1828条经验 获得超13个赞
你可以使用格洛姆。
from glom import glom
target = {'a': {'b': {'c': 'd'}}}
glom(target, 'a.b.c', default=None) # returns 'd'
https://github.com/mahmoud/glom
TA贡献1873条经验 获得超9个赞
结合我在这里看到的一些东西。
from functools import reduce
def optional_chain(obj, keys):
try:
return reduce(getattr, keys.split('.'), obj)
except AttributeError:
return None
optional_chain(foo, 'bar.baz')
或者扩展,getattr这样你也可以使用它作为替代品getattr
from functools import reduce
def rgetattr(obj, attr, *args):
def _getattr(obj, attr):
return getattr(obj, attr, *args)
return reduce(_getattr, attr.split('.'), obj)
如果路径不存在,它仍然可以引发一个,并且您可以指定自己的默认值而不是“无” rgetattr。AttributeError
TA贡献1818条经验 获得超11个赞
将其他一些答案组合到一个函数中可以为我们提供易于阅读的内容以及可以与对象和字典一起使用的内容。
def optional_chain(root, *keys):
result = root
for k in keys:
if isinstance(result, dict):
result = result.get(k, None)
else:
result = getattr(result, k, None)
if result is None:
break
return result
使用此函数,您只需在第一个参数之后添加键/属性。
obj = {'a': {'b': {'c': {'d': 1}}}}
print(optional_chain(obj, 'a', 'b'), optional_chain(obj, 'a', 'z'))
给我们:
{'c': {'d': 1}} None
TA贡献1828条经验 获得超3个赞
类可以覆盖__getattr__以返回缺失属性的默认值:
class Example:
def __getattr__(self, attr): # only called when missing
return None
测试它:
>>> ex = Example()
>>> ex.attr = 1
>>> ex.attr
1
>>> ex.missing # evaluates to `None
>>>
但是,这不允许链接:
>>> ex.missing.missing
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'missing'
它也不会处理调用不存在的方法的尝试:
>>> ex.impossible()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
为了解决这个问题,我们可以创建一个代理对象:
class GetAnything:
def __getattr__(self, attr):
return self
def __call__(self, *args, **kwargs): # also allow calls to work
return self
def __repr__(self):
return '<Missing value>'
# Reassign the name to avoid making more instances
GetAnything = GetAnything()
并返回它而不是None:
class Example:
def __getattr__(self, attr): # only called when missing
return GetAnything
现在它根据需要链接:
>>> Example().missing_attribute.missing_method().whatever
<Missing value>
添加回答
举报