Fel*_*lix 14 python attributes exception-handling isinstance
我试图找出确定是否obj可以执行操作的对象的不同方法之间的权衡do_stuff().据我了解,有三种方法可以确定这是否可行:
# Way 1
if isinstance(obj, Foo):
obj.do_stuff()
# Way 2
if hasattr(obj, 'do_stuff'):
obj.do_stuff()
# Way 3
try:
obj.do_stuff()
except:
print 'Do something else'
Run Code Online (Sandbox Code Playgroud)
哪种方法首选(以及为什么)?
iCo*_*dez 10
我相信Python编码器通常首选最后一种方法,因为Python社区教授的座右铭是:"更容易请求宽恕而非许可"(EAFP).
简而言之,座右铭意味着避免在你做之前检查你是否可以做某事.相反,只需运行该操作.如果失败,请妥善处理.
而且,第三种方法具有额外的优点,即清楚地表明操作应该起作用.
话虽如此,你真的应该避免使用这样的裸露except.这样做会捕获任何/所有异常,甚至是不相关的异常.相反,最好特别捕获异常.
在这里,您需要捕获AttributeError:
try:
obj.do_stuff() # Try to invoke do_stuff
except AttributeError:
print 'Do something else' # If unsuccessful, do something else
Run Code Online (Sandbox Code Playgroud)
检查isinstance运行与使用duck typing的Python约定相反.
hasattr工作正常,但是在你跳跃之前,而不是更多的Pythonic EAFP.
您对方式3的实现很危险,因为它可以捕获任何和所有错误,包括由do_stuff方法引发的错误.你可以更精确地去:
try:
_ds = obj.do_stuff
except AttributeError:
print('Do something else')
else:
_ds()
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,我更喜欢方式2,尽管有轻微的开销 - 它更具可读性.
小智 5
正确的答案是“都不”\nhasattr 提供功能,但它可能是所有选项中最糟糕的。
\n\n我们使用 Python 的面向对象特性,因为它有效。面向对象的分析从来都不准确,而且常常令人困惑,但我们使用类层次结构,因为我们知道它们可以帮助人们更快地更好地工作。人们掌握对象,良好的对象模型可以帮助编码人员更快地更改事物并减少错误。正确的代码最终会聚集在正确的位置。对象:
\n\nhasattr 与 isinstance
\n\n必须使用 isinstance 或 hasattr 表明对象模型已损坏或我们使用不正确。正确的做法是修复对象模型或改变我们使用它的方式。\n这两个构造具有相同的效果,并且在命令式 \xe2\x80\x98 中我需要代码来执行此操作\xe2\x80\x99 感觉它们是等效的。结构上存在巨大差异。第一次遇到此方法时(或在做了其他事情几个月后), isinstance 传达了有关实际发生的情况以及其他可能发生的情况的更多信息。Hasattr 不会告诉你任何东西。
\n\n悠久的发展历史使我们远离了 FORTRAN 和带有大量 \xe2\x80\x98who am I\xe2\x80\x99 开关的代码。我们选择使用对象是因为我们知道它们有助于使代码更易于使用。通过选择 hasattr,我们提供了功能,但是没有修复任何内容,代码比我们开始之前更加破碎。将来添加或更改此功能时,我们将不得不处理不均匀分组且至少有两个组织原则的代码,其中一些是 \xe2\x80\x98 应该是 \xe2\x80\x99 的位置,其余的则在 \xe2\x80\x98 的位置随机分散在其他地方。没有什么可以使它连贯。这不是一个错误,而是一个潜在错误的雷区,分散在经过您的 hasattr 的任何执行路径上。
\n\n所以如果有选择的话,顺序是:
\n\n| 归档时间: |
|
| 查看次数: |
4413 次 |
| 最近记录: |