0

看看这段代码:

>>> class c(object):
...    pass
... 
>>> a=c()
>>> if a.b.c:
...    print 'hello'
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'c' object has no attribute 'b'

安静的!这不是问题。请继续阅读:

当有人开发企业软件(例如使用 django)时,必须编写业务规则。这个规则看起来像

if invoice.customer.adress.country in ...:
    invoice.makeSomeSpecialOffer()

但有时,表达所涉及的对象之一并不存在。然后,为了避免错误,我将句子改写为:

if invoice.customer and
   invoice.customer.adress and
   invoice.customer.adress.country and
   invoice.customer.adress.country in ...

这可读性差!(您也可以尝试使用 hasattr 但可读性较差)。

我的工作是将 if 语句包含在 try 中,但是有一种更优雅或 pythatonic 的方式来避免这种错误?你最喜欢哪种技术?

4

2 回答 2

2

要检查链接属性,以下函数可能会有所帮助:

def get_chainedattr(parobj, *args):
    try:        
        ret = parobj
        for arg in args:
            ret = getattr(ret, arg)   
        return ret
    except AttributeError:
        return None

我不确定它是否更具可读性,但通过使用这个函数,你的例子可以写成:

if get_chainedattr(invoice, "customer", "adress", "country") in ...:
   invoice.makeSomeSpecialOffer()
于 2011-12-10T17:10:10.657 回答
1

This is less readable! (also you can try with hasattr but is alse less readable).

Another option would be to enclose in a try 'except block.

try:
    if invoice.customer.adress.country in ...:
        invoice.makeSomeSpecialOffer()
except AttributeError:
    None

Either you can make a proactive check like hasattr or a reactive like try-except. Readability is a perception and both the approach is except-able.

于 2011-12-10T15:54:45.020 回答