Dyn*_* Fu 9 python coding-style exception
选项1:
def f1(c):
d = {
"USA": "N.Y.",
"China": "Shanghai"
}
if c in d:
return d[c]
return "N/A"
Run Code Online (Sandbox Code Playgroud)
选项2:
def f2(c):
d = {
"USA": "N.Y.",
"China": "Shanghai"
}
try:
return d[c]
except:
return "N/A"
Run Code Online (Sandbox Code Playgroud)
这样我就可以打电话:
for c in ("China", "Japan"):
for f in (f1, f2):
print "%s => %s" % (c, f(c))
Run Code Online (Sandbox Code Playgroud)
选项是确定密钥是否在预先存在于目录中(f1),或者只是回退到异常(f2).哪一个更受欢迎?为什么?
Dav*_*ick 21
我也不会这样做
def f2(c):
d = {
"USA": "N.Y.",
"China": "Shanghai"
}
return d.get(c, "N/A")
Run Code Online (Sandbox Code Playgroud)
这种方式更短,"get"专为工作而设计.
另外一个没有明确异常的例外是糟糕的实践,所以except KeyError:不要只使用除外.
例外在python中没有太多开销.如果没有更好的替代方案或有时甚至在保存属性查找(使用而不是hasattr)时使用它们通常更好.
编辑:清除关于例外的一般观点.
paxdiablo在一般方面是正确的.Python主要是为"它更容易请求原谅然后允许",即尝试然后查看失败(例外),然后"在你跳跃之前看"然后看看那里然后申请.这是因为python中的属性查找可能很昂贵,因此再次调用相同的东西(检查边界)是浪费资源.但是,python中的内部函数通常都有更好的帮助程序,所以最好使用它们.
pax*_*blo 11
一般而言(不一定是Python),除了最简单的情况之外,我倾向于选择"尝试然后告诉我,如果它错了"方法(例外).这是因为,在线程环境中或在数据库访问期间,基础数据可以在密钥检查和值提取之间变化.
如果您没有更改当前线程之外的关联数组,那么您可以执行"先检查然后提取"方法.
但这是一般情况.在这里,具体来说,您可以使用get允许您在密钥不存在时指定默认值的方法:
return d.get (c, "N/A")
Run Code Online (Sandbox Code Playgroud)
我将澄清我在第一段中所述的内容.在基础数据可以在检查和使用之间更改的情况下,应始终使用异常类型操作(除非您有一个不会导致问题的操作,例如d.get(),如上所述).考虑以下两个线程时间线:
+------------------------------+--------------------+
| Thread1 | Thread2 |
+------------------------------+--------------------+
| Check is NY exists as a key. | |
| | Delete NY key/val. |
| Extract value for NY. | |
+------------------------------+--------------------+
Run Code Online (Sandbox Code Playgroud)
当线程1尝试提取值时,无论如何它都会得到一个异常,所以你也可以只编写可能性的代码并删除初始检查.
关于数据库的评论也是相关的,因为这是基础数据可以改变的另一种情况.这就是为什么我倾向于选择原子SQL(在可能的情况下),而不是像获取密钥列表然后用单独的语句处理它们.
通常,异常带来一些开销,并且用于真正"特殊"的情况.在这种情况下,这听起来像执行的正常部分,而不是"异常"或"错误"状态.
一般来说,我认为您的代码将通过使用"if/else"约定而受益,并且仅在真正需要时保存异常.
| 归档时间: |
|
| 查看次数: |
367 次 |
| 最近记录: |