哪种款式首选?

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中的内部函数通常都有更好的帮助程序,所以最好使用它们.

  • 我会说"就这么做",但要确保你知道会出错.不要抓住一切,只有特别的例外,你很乐意发生.如果你抓住了一切,当出现严重问题时,很难找到,因为你不会得到任何反馈. (2认同)

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(在可能的情况下),而不是像获取密钥列表然后用单独的语句处理它们.


Jon*_*n W 9

通常,异常带来一些开销,并且用于真正"特殊"的情况.在这种情况下,这听起来像执行的正常部分,而不是"异常"或"错误"状态.

一般来说,我认为您的代码将通过使用"if/else"约定而受益,并且仅在真正需要时保存异常.

  • 这让我想起了"你想的代码","事情做得更好".所以我把它标记为答案. (2认同)
  • 这是一个好点jeffjose.在python中很聪明地尝试一下,看看哪些有用.但是,在这种情况下,当我们不期望任何异常时使用try/except子句不是一个好主意.像里奇一样说:"恶业".:-) (2认同)

Ign*_*ams 7

都不是.

return d.get(c, 'N/A')
Run Code Online (Sandbox Code Playgroud)