嵌套属性的hasattr

4 投票
7 回答
4959 浏览
提问于 2025-04-18 13:31

我需要类似这样的东西(伪代码):

if hasattr(object, 'detail.infotext')

我的意思是,我想检查一个对象是否有一个叫做 details 的属性,如果有的话,再检查这个 details 是否有一个叫 infotext 的属性。

我可以这样做:

if hasattr(object, 'detail'):
    if hasattr(object.detail, 'infotext'):
        do something

但是一行代码看起来更容易理解。

7 个回答

0

这是一个老问题,但这里有另一种方法,基于这个答案,它提供了一个很好的解决方案,用于处理嵌套的getattr...

import functools

def rhasattr(obj, path):
    try:
        functools.reduce(getattr, path.split("."), obj)
        return True
    except AttributeError:
        return False
0

虽然没有测试过,但应该是可以用的:

def hasattrpath(obj, path):
    parts = path.split(".")
    for part in parts:
        if hasattr(obj, part):
            obj = getattr(obj, part)
        else:
            return False
    else:
        return True

不过,除非你在代码的每个地方都有这种深层嵌套的路径表达式的测试,否则jonrsharpe的评论可能是最简单直接的解决方案。

0

我之前在我的项目中用过类似的东西;

attr = 'detail.infotext'.split('.')
if len(attr) == 1:
    return getattr(item, attr[0], "")
else:
    return getattr(getattr(item, attr[0], ""), attr[1], "")

或者,也可以用一句话来写;

    attr = "detail.infotext"
    if hasattr(item, attr.rsplit('.', 1)[0]) and hasattr(getattr(item, attr.rsplit('.', 1)[0]), attr.rsplit('.', 1)[1]):
        pass
4

假设你想真正使用你的属性值,operator.attrgetter(在Python 2.6及以上版本中)可能会很有用。除了需要处理一个异常之外,其他的都比较简单明了:

from operator import attrgetter

try:
   print attrgetter("detail.infotext")(object)
except:
   <handle exception>
6

我知道这可能不是你真正想要做的,但这样做更符合Python的风格(如果你明确知道你要找的属性名称的话):

try:
   do something with object.detail.infotext
except AttributeError:
   do something else

撰写回答