简洁的getattr()方法,如果不是Python中的None,则使用它

Oli*_*eng 30 python

我发现自己经常做以下事情:

attr = getattr(obj, 'attr', None)
if attr is not None:
    attr()
    # Do something, either attr(), or func(attr), or whatever
else:
    # Do something else
Run Code Online (Sandbox Code Playgroud)

有更多的pythonic写作方式吗?这是否更好?(至少没有表现,IMO.)

try:
    obj.attr() # or whatever
except AttributeError:
    # Do something else
Run Code Online (Sandbox Code Playgroud)

Joe*_*erg 36

既然你正在打电话attr,你可以这样做:

def default_action():
    # do something else

action = getattr(obj, 'attr', default_action)

action()
Run Code Online (Sandbox Code Playgroud)


Val*_*ntz 13

与Joe的答案类似,但更短:

getattr(obj, 'attr', lambda: None)()
Run Code Online (Sandbox Code Playgroud)


paj*_*ton 7

还有另一个很好的习语:

if hasattr(obj, 'attr'):
    ...something...
else:
    ...something else...
Run Code Online (Sandbox Code Playgroud)

从您发布的两个选项中我更喜欢第一个选项.在访问成员时抛出异常的概念似乎并不是例外意图用来做的事情.

  • 这是一个悬而未决的问题.在这种情况下,我没有发现使用`AttributeError`是一种很好的做法.这是否意味着你是对的而我不是?我不这么认为 (3认同)

Ale*_*lli 7

在您编写代码时,try/ exceptalternative可能会意外地导致被调用的AttributeError任何内容中的问题导致attr()被捕获.如果你想使用try/ 进行编码except,这是合理的并且如果缺少属性很少,那么使用:

try:
  attr = obj.attr
except AttributeError:
  dosome(thingelse)
else:
  attr()
Run Code Online (Sandbox Code Playgroud)

这不会导致"意外捕获"如上所述.关于哪种方法更可取,我通常采用例外捕捉方法 - "EAFP","比宽容更容易请求宽恕"(通常归功于海军上将Grace Hopper,COBOL和CODASYL背后的驱动力)绝对适用很好的Python ;-).