返回介绍

建议23:使用 else 子句简化循环(异常处理)

发布于 2024-01-30 22:19:09 字数 2268 浏览 0 评论 0 收藏 0

有其他编程语言经验的程序员接触到Python时,对于它无所不在的else往往感到非常惊讶。在Python中,不仅分支语句有else子句,而且循环语句也有,甚至连异常处理也有。首先来看看循环语句中的else,看看它们的语法。

while_stmt ::=  "while" expression ":" suite
        ["else" ":" suite]
for_stmt ::=  "for" target_list "in" expression_list ":" suite
        ["else" ":" suite]

从语法定义中可以看到如果没有["else" ":" suite]这一块,Python的循环语句跟大多数语言并无二致。要谈else子句,必须先从Python从其他语言中借鉴的语义相同的break语句说起,因为else子句提供了隐含的对循环是否由break语句引发循环结束的判断。先来看一个没有应用else子句的例子:

def print_prime(n):
  for i in xrange(2, n):
    found = True
    for j in xrange(2, i):
      if i % j == 0:
        found = False
        break
    if found:
      print '%d is a prime number'%i

这是一个查找素数的简单实现,可以看到我们借助了一个标志量found来判断是循环结束是不是由break语句引起的。如果对else善加利用,代码可以简洁得多。来看下面的具体实现:

def print_prime2(n):
  for i in xrange(2, n):
    for j in xrange(2, i):
      if i % j == 0:
        break
    else:
      print '%d is a prime number'%i

当循环“自然”终结(循环条件为假)时else从句会被执行一次,而当循环是由break语句中断时,else子句就不被执行。与for语句相似,while语句中的else子句的语意是一样的:else块在循环正常结束和循环条件不成立时被执行。

与C/C++等较为“老土”的语言相比,else子句使程序员的生产力和代码的可读性都得到了提高,所以建议大家多使用else,让程序变得更加Pythonic。

在Python的异常处理中,也提供了else子句语法,这颗“语法糖”的意义跟循环语句中的else是相似的:try块没有抛出任何异常时,执行else块。按惯例先看一下如下语法定义:

try_stmt  ::=  try1_stmt | try2_stmt
try1_stmt ::=  "try" ":" suite
         ("except" [expression [("as" | ",") target]] ":" suite)+
         ["else" ":" suite]
         ["finally" ":" suite]
try2_stmt ::=  "try" ":" suite
         "finally" ":" suite

从try1_stmt的定义中可以看到,Python的异常处理中有一种try-except-else-finally形式。下面的例子是把数据写入文件中。

def save(db, obj):
  try:
    # save attr1
    db.execute('a sql stmt', obj.attr1)
    # save attr2
    db.execute('another sql stmt', obj.attr2)
  except DBError:
    db.rollback()
  else:
    db.commit()

如果没有else子句,就像前文中关于循环的例子一样,需要引入一个标志变量。

def save(db, obj):
  some_error_occurred = False
  try:
    # save attr1
    db.execute('a sql stmt', obj.attr1)
    # save attr2
    db.execute('another sql stmt', obj.attr2)
  except DBError:
    db.rollback()
    some_error_occurred = True
  if not some_error_occurred:
    db.commit()

这样代码就变得复杂了。在Python中还有不少语法都是致力于让程序员可以编写更加简明、更接近自然语言语义的代码,比如in和with语句(将在其他章中讲述相关用法),这也证明充分地学习手册中的Language Reference非常有必要。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文