我发现自己经常做以下事情:
attr = getattr(obj, 'attr', None)
if attr is not None:
attr()
# Do something, either attr(), or func(attr), or whatever
else:
# Do something else
有更多的pythonic写作方式吗?这是否更好? (至少没有表现,IMO。)
try:
obj.attr() # or whatever
except AttributeError:
# Do something else
答案 0 :(得分:36)
由于您正在呼叫attr
,您可以这样做:
def default_action():
# do something else
action = getattr(obj, 'attr', default_action)
action()
答案 1 :(得分:12)
与Joe的答案相似,但更短:
getattr(obj, 'attr', lambda: None)()
答案 2 :(得分:7)
还有另一个很好的习语:
if hasattr(obj, 'attr'):
...something...
else:
...something else...
从您发布的两个选项中我更喜欢第一个选项。在访问成员时抛出异常的概念似乎并不是例外意图用来做的事情。
答案 3 :(得分:7)
try
/ except
替代方案,在您编写代码时,可能会意外导致AttributeError
因attr()
正在调用的任何问题而导致try
被捕获。如果您想使用except
/ try:
attr = obj.attr
except AttributeError:
dosome(thingelse)
else:
attr()
进行编码,如果该属性很少丢失,这是合理且表现良好的,请使用:
{{1}}
这将不导致“意外捕获”如上所述。关于哪种方法更可取,我通常采用例外捕捉方法 - “EAFP”,“比宽容更容易请求宽恕”(通常归功于海军上将Grace Hopper,COBOL和CODASYL背后的驱动力)绝对适用很好的Python; - )。
答案 4 :(得分:1)
使用try / except通常被认为更加pythonic。如果obj具有该属性,它也更有效,因为它消除了测试 - 如果不抛出异常,try块没有开销。另一方面,如果obj没有该属性,则效率较低,因为它将具有抛出和捕获异常的开销。
答案 5 :(得分:1)
啊,这取决于确切的代码。你的两个工具:
以下是最常见的情况:
the_name = getattr(user, 'name', '<Unknown User>')
user.name = getattr(user, 'name', '<Unknown User>')
if not hasattr(name, 'user'):
try_asking_again()
name = user.name if hasattr(user, 'name') else do_expensive_name_lookup(user)
要更好地了解整个过程,请查看以下代码段:
class Thing():
def __init__(self):
self.a = 'A'
def __getattr__(self, attr):
if attr == "b":
return "B"
else:
raise AttributeError("Thing instance has no attribute '" + attr + "'")
item = Thing()
print "hasattr(a) is " + str(hasattr(item, "a"))
print "a is " + item.a
print "hasattr(b) is " + str(hasattr(item, "b"))
print "b is " + item.b
out = "c is " + item.c if hasattr(item, "c") else "No C"
print out
print "and c is also " + getattr(item, "c", "Not Assigned")
print "c throws an Attribute exception " + item.c
有这个输出:
hasattr(a) is True
a is A
hasattr(b) is True
b is B
No C
and c is also Not Assigned
Traceback (most recent call last):
File "attr_snippet.py", line 23, in <module>
print "c throws an Attribute exception " + item.c
File "attr_snippet.py", line 9, in __getattr__
raise AttributeError("Thing instance has no attribute '" + attr + "'")
AttributeError: Thing instance has no attribute 'c'
答案 6 :(得分:0)
object.attr() if hasattr(object, 'attr') else None
参数是一个对象和一个字符串。如果字符串是对象属性之一的名称,则结果为 True,否则为 False。 (这是通过调用 getattr(object, name) 并查看它是否引发 AttributeError 来实现的。)