其他控制语句,也就是说一个with... as...语句。

  这是python非常精妙的一个语句,非常的简单但是作用非常大,在打开文件获得句柄的时候可以用它,省去f.close()忘记添加的麻烦(这个文件的IO操作会用到)。

1.   with语句时什么?

  有一些任务,可能实现需要设置,时候做清理工作。对于这种场景,python的with语句提供了一种非常方便的处理方式。一个很好的例子就是文件处理,你需要获得文件句柄,从文件中读取数据,然后关闭文件。

  如果不用with语句,代码如下:

 file = open("/tmp/foo.txt")
data = file.read()
file.close()

  这里有两个问题。一是可能忘记关闭文件句柄;而是文件读取数据发生异常,没有进行任何处理。

  如果采用with的话,除了有更优雅的语法,with还可以很好的处理上下文环境产生的异常。

 with open("/tmp/foo.txt") as file:
data = file.read()

2.   with是怎么工作的?

  我们有了上的这个例子可以得出with...as..的方法

  这看起来充满魔法,但不仅仅是魔法,Python对with的处理还很聪明。基本思想是with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。

  下面例子可以具体说明with如何工作:

 class Sample:
def __enter__(self):
print "In __enter__()"
return "Foo" def __exit__(self, type, value, trace):
print "In __exit__()" def get_sample():
return Sample() with get_sample() as sample:
print "sample:", sample

  运行代码,输出如下:

  In __enter__()
  sample: Foo
  In __exit__()

  正如你看到的
  1. __enter__()方法被执行
  2. __enter__()方法返回的值 - 这个例子中是"Foo",赋值给变量'sample'
  3. 执行代码块,打印变量"sample"的值为 "Foo"
  4. __exit__()方法被调用
  with真正强大之处是它可以处理异常。可能你已经注意到Sample类的__exit__方法有三个参数- val, type 和 trace。 这些参数在异常处理中相当有用。我们来改一下代码,看看具体如何工作的。

  举例如下:

class Sample:
def __enter__(self):
return self def __exit__(self, type, value, trace):
print "type:", type
print "value:", value
print "trace:", trace def do_something(self):
bar = 1/0
return bar + 10 with Sample() as sample:
sample.do_something()

  这个例子中,with后面的get_sample()变成了Sample()。这没有任何关系,只要紧跟with后面的语句所返回的对象有__enter__()和__exit__()方法即可。此例中,Sample()的__enter__()方法返回新创建的Sample对象,并赋值给变量sample。
代码执行后:

 bash-3.2$ ./with_example02.py
type: <type 'exceptions.ZeroDivisionError'>
value: integer division or modulo by zero
trace: <traceback object at 0x1004a8128>
Traceback (most recent call last):
File "./with_example02.py", line 19, in <module>
sample.do_something()
File "./with_example02.py", line 15, in do_something
bar = 1/0
ZeroDivisionError: integer division or modulo by zero

  实际上,在with后面的代码块抛出任何异常时,__exit__()方法被执行。正如例子所示,异常抛出时,与之关联的type,value和stack trace传给__exit__()方法,因此抛出的ZeroDivisionError异常被打印出来了。开发库时,清理资源,关闭文件等等操作,都可以放在__exit__方法当中。
  因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。

另外,在异常处理单元,我们说过一个except...as...,请参照条件控制语句的异常处理部分

3. 其他控制语句

  3.1 推导式:

  推导式(comprehensions)又称为解析式,是Python的一种独有的特性。推导式可以从一个数据序列构建另一个新的数据序列的结构体。常用的有三种推导式,其他推导式跟这个形式一样。

  格式:推导式(以列表推导式为例)

  variable = [out_exp_res for out_exp in input_list if out_exp == 2]

  举例1:列表推导式

multiples = [i for i in range() if i %  is ]
print(multiples)
# Output: [, , , , , , , , , ]

  举例2:使用() 生成generator

multiples = (i for i in range() if i %  is )
print(type(multiples))
# Output: <type 'generator'>

  举例3:大小写key合并

mcase = {'a': , 'b': , 'A': , 'Z': }
mcase_frequency = {
k.lower(): mcase.get(k.lower(), ) + mcase.get(k.upper(), )
for k in mcase.keys()
if k.lower() in ['a','b']
}
print mcase_frequency
# Output: {'a': , 'b': }

  举例4:快速更换key和value

mcase = {'a': , 'b': }
mcase_frequency = {v: k for k, v in mcase.items()}
print mcase_frequency
# Output: {: 'a', : 'b'}

  举例5:集合推导式

squared = {x** for x in [, , ]}
print(squared)
# Output: set([, ])

Python笔记_第一篇_面向过程_第一部分_6.其他控制语句(with...as等)的更多相关文章

  1. Python笔记_第一篇_面向过程_第一部分_2.内存详解

    Python的很多教材中并没有讲内存方面的知识,但是内存的知识非常重要,对于计算机工作原理和方便理解编程语言是非常重要的,尤其是小白,因此需要把这一方面加上,能够更加深入的理解编程语言.这里引用了C语 ...

  2. Python笔记_第一篇_面向过程_第一部分_6.条件控制语句(if)

    Python正如其他语言一样存在两种常用的逻辑判断体(也叫结构化程序设计).所谓逻辑判断体是通过你想要完成的编程思路,通过在逻辑判断体中的相互判断和作用得到你想要的结果.逻辑判断体也叫控制语句,Pyt ...

  3. Python笔记_第二篇_面向过程_第二部分_2.路径、栈和队列、内存修改

    这一部分分三个主题进行讲解,主要为后面的模块.包.第三方库的概念补充一些相关的内容. 1. 路径(Path): 相对路径和绝对路径. 举例1:我们先导入一个os库(模块)来观察一下路径 import ...

  4. 四、java基础-面向过程_对象_类中可出现的因素

    1.面向过程和面向对象区别: 1)面向过程:开发一个应用程序.一个项目,必须先了解整个过程,了解各个步骤.模块间的因果关系,使的面向过程方式去开发程序时,代码和代码之间的关联程度是非常强.所以其中任何 ...

  5. python自动化开发-[第五天]-面向过程、模块、包

    今日概要: 1.内置模块 2.协程函数 3.递归 4.面向过程编程与函数编程 5.模块 6.包 7.re正则 一.内置模块 1.匿名函数lambda 定义:匿名函数通常是创建了可以被调用的函数,它返回 ...

  6. python第四周迭代器生成器序列化面向过程递归

      第一节装饰器复习和知识储备------------ 第一节装饰器复习和知识储备------------ def wrapper(*args,**kwargs): index(*args,**kwa ...

  7. [Python笔记]第八篇:模块

    本篇主要内容:python常用模块用法介绍 什么是模块 模块,用一大段代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性 ...

  8. [Python笔记]第三篇:深浅拷贝、函数

    本篇主要内容:深浅拷贝,自定义函数,三目运算,lambda表达式, 深浅拷贝 一.数字和字符串 对于 数字 和 字符串 而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址. import ...

  9. python之迭代器、生成器、面向过程编程

    一 迭代器 一 迭代的概念 #迭代器即迭代的工具,那什么是迭代呢?#迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,因而不 ...

  10. python函数之协程与面向过程编程

    第一:协程 初步了解协程 def eater(): print('start to eat') while True: food=yield print('is eating food:%s'%foo ...

随机推荐

  1. UVA - 1615 Highway(高速公路)(贪心+区间选点)

    题意:给定平面上n(n<=105)个点和一个值D,要求在x轴上选出尽量少的点,使得对于给定的每个点,都有一个选出的点离它的欧几里德距离不超过D. 分析: 1.根据D可以算出每个点在x轴上的可选区 ...

  2. ofo身陷被收购、破产传闻,中国的共享单车还能活下去吗?

    大潮退去,终将现出谁在"裸泳".尤其是那些看似火爆却迅速陨落的新事物,总是避免不了让人发出"伤仲永"的感慨.这其中,共享经济就是很典型的案例.共享睡眠舱.共享马 ...

  3. 热衷外卖的韩国与中国,外卖APP最大的区别有哪些?

    额,一向"自大"的韩国人总是想处处争先.就连在外卖方面,韩国人也说自己的"外卖民族",对外卖有着一种"痴迷".事实上,早在20多年前韩国外卖 ...

  4. Windows环境安装与搭建node.js环境

    参考文章:https://www.cnblogs.com/zhouyu2017/p/6485265.html 一.下载node.js,直接下一步至安装完成.https://nodejs.org/en/ ...

  5. dns、网关、IP地址,主要是配置resolv.conf\network\ifcfg-eth0

    Ubuntu sudo vi /etc/network/interfac   添加 dns-nameservers 192.168.1.254dns-search stonebean.com cent ...

  6. 基于云开发开发 Web 应用(四):引入统计及 Crash 收集

    在完成了产品的基础开发以后,接下来需要进行一些周边的工作,这些周边工具将会帮助下一步优化产品. 为什么要加应用统计和 Crash 收集 不少开发者在开发的时候,很少会意识到需要添加应用统计和 Cras ...

  7. 学术Essay写作中Introduction的正确打开方式

    其实在学术essay写作过程中,很多留学生经常不知道如何写introduction,所以有些开头的模板句就出现了,比如,With the development of society/With the ...

  8. lp_wizard 安装和使用

    lp_wizard 安装好之后,安装下面的步骤来和谐: 生成封装安装下面的步骤来做: 封装生成完了之后,注意后缀是 .pad 的需要放入自己的 pad 文件夹,.fsm 的放入 flash 文件夹,. ...

  9. mariadb主从

    实验环境: 两台centos7 master:192.168.1.6 slave:192.168.1.7 一.安装mariadb服务 [root@master ~]# yum -y install m ...

  10. VS常用高效快捷键

    快捷键的使用能够提供我们写代码的效率.还能装逼(哈哈O(∩_∩)O~) 类别 快捷键 描述 编辑 Ctrl+S 保存(养成好习惯,停下来的时候就保存下,不然遇见突发情况会很崩溃的) Ctrl+Shif ...