对于要确保即使发生一个错误时也能运行一些清理代码而言,try...finally语句是很有用的。对此有许多使用场景,例如:
- 关闭一个文件
- 释放一个锁
- 创建一个临时的代码补丁
- 在特殊环境中运行受保护的代码
with语句覆盖了这些使用场景,为在一个代码块前后调用一些代码提供了一种简单的方法。例如,使用一个文件通常可以如下实现。
hosts = file('/etc/hosts')
try:
for line in hosts:
if line.startswith('#'):
continue
print line
finally:
hosts.close()
使用with语句,以上代码可以重写如下:
from __future__ import with_statement
with file('/etc/hosts') as hosts:
for line in hosts:
if line.startswith('#'):
contine
print host
注意,在2.5版本中with语句仍然位于__future__模块里,而在2.6版本中则可以直接使用。
与这条语句兼容的其他项目是来自thread和threading模块的类:
- thread.LockType
- threading.Lock
- threading.RLock
- threading.Condition
- threading.Semaphore
- threading.BoundedSemaphore
这些类都实现两个方法__enter__和__exit__,这都来自于with协议。换句话说,任何类都可以实现为如下的所示:
class Context(object):
def __enter__(self):
print 'entering the zone'
def __exit__(self, exception_type, exception_value, exception_traceback):
print 'leaving the zone'
if exception_type is None:
print 'with no error'
else:
print 'with an error (%s)' % exception_value
with Context():
print 'i am the zone'
with Context():
print 'i am the buggy zone'
raise TypeError('i am the bug')
Python2.5新增if-else条件表达式
条件表达式,C风格的如下:
condition? exp1 : exp2
也称为三元表达式。
Python2.5新增了这一功能,但形式有了变化:
exp1 if condition else exp2
实例:
>>> a = 1 if 2 == 3 else 4
>>> a
4
>>> isLeapYear = lambda year: not (year % 4 if year % 100 else year % 400) # 判断闰年
>>> isLeapYear(1234)
False
>>> isLeapYear(1236)
True
>>> isLeapYear(1000)
False
>>> isLeapYear(2000)
True
>>> [i + 1 if i % 2 for i in xrange(10)] # 不能省略else
File "<stdin>", line 1
[i + 1 if i % 2 for i in xrange(10)]
^
SyntaxError: invalid syntax
>>> [i + 1 if i % 2 else i for i in xrange(10)]
[0, 2, 2, 4, 4, 6, 6, 8, 8, 10]
>>> [i % 2 and i + 1 or i for i in xrange(10)] # 之前的语法
[0, 2, 2, 4, 4, 6, 6, 8, 8, 10]