如何链接可能在Python中返回None的属性查找?
我的问题是一个一般的问题,当中间一个可能返回时,如何链接一系列属性查找None
,但是由于我在尝试使用Beautiful
Soup时遇到了这个问题,因此我将在这种情况下提出该问题。
Beautiful
Soup解析HTML文档并返回一个对象,该对象可用于访问该文档的结构化内容。例如,如果解析的文档在变量中soup
,则可以使用以下命令获取其标题:
title = soup.head.title.string
我的问题是,如果文档没有标题,则soup.head.title
返回None
,随后的string
查找将引发异常。我可以将链分解为:
x = soup.head
x = x.title if x else None
title = x.string if x else None
但是在我看来,这是冗长且难以阅读的。
我可以写:
title = soup.head and soup.head.title and soup.title.head.string
但这是冗长且低效的。
如果可以想到的一种解决方案(我认为是可行的)将是创建一个对象(称为nil
),该对象None
将为任何属性查找返回。这可以让我写:
title = ((soup.head or nil).title or nil).string
但这很丑。有没有更好的办法?
-
您可能可以使用
reduce
此功能:>>> class Foo(object): pass ... >>> a = Foo() >>> a.foo = Foo() >>> a.foo.bar = Foo() >>> a.foo.bar.baz = Foo() >>> a.foo.bar.baz.qux = Foo() >>> >>> reduce(lambda x,y:getattr(x,y,''),['foo','bar','baz','qux'],a) <__main__.Foo object at 0xec2f0> >>> reduce(lambda x,y:getattr(x,y,''),['foo','bar','baz','qux','quince'],a) ''
在python3.x中,我认为它
reduce
已移至functools
:(
我想您也可以使用更简单的功能来做到这一点:
def attr_getter(item,attributes) for a in attributes: try: item = getattr(item,a) except AttributeError: return None #or whatever on error return item
最后,我想 最好的 方法是:
try: title = foo.bar.baz.qux except AttributeError: title = None