码迷,mamicode.com
首页 > 编程语言 > 详细

[Python] Symbol Review

时间:2016-06-28 20:12:22      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:

From: http://learnpythonthehardway.org/book/ex37.html

 

1. with X as Y: pass

1.1 yield 

2. exec

2.1 namespace

  


技术分享

KEYWORDDESCRIPTIONEXAMPLE
and Logical and. True and False == False
as (1) Part of the with-as statement. with X as Y: pass
assert Assert (ensure) that something is true. assert False, "Error!"
break Stop this loop right now. while True: break
class Define a class. class Person(object)
continue Don‘t process more of the loop, do it again. while True: continue
def Define a function. def X(): pass
del Delete from dictionary. del X[Y]
elif Else if condition. if: X; elif: Y; else: J
else Else condition. if: X; elif: Y; else: J
except If an exception happens, do this. except ValueError, e: print e
exec (2) Run a string as Python. exec ‘print "hello"‘
finally Exceptions or not, finally do this no matter what. finally: pass
for Loop over a collection of things. for X in Y: pass
from Importing specific parts of a module. from x import Y
global Declare that you want a global variable. global X
if If condition. if: X; elif: Y; else: J
import Import a module into this one to use. import os
in Part of for-loops. Also a test of X in Y. for X in Y: pass also 1 in [1] == True
is Like == to test equality. 1 is 1 == True
lambda (3) Create a short anonymous function. s = lambda y: y ** y; s(3)
not Logical not. not True == False
or Logical or. True or False == True
pass (4) This block is empty. def empty(): pass
print Print this string. print ‘this string‘
raise (5) Raise an exception when things go wrong. raise ValueError("No")
return Exit the function with a return value. def X(): return Y
try Try this block, and if exception, go to except. try: pass
while While loop. while X: pass
with With an expression as a variable do. with X as Y: pass
yield (1.1) Pause here and return to caller. def X(): yield Y; X().next()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1. with-as statement(也称context manager)


From: http://zhoutall.com/archives/325

 

(1) 常见写法,但比较啰嗦

try:
    f = open(xxx)
except:
    print fail to open
    exit(-1)
try:
    do something
except:
    do something
finally:
    f.close()

 

(2) 使用封装如何?不用反复写finally,但导致:所有的函数都要被 controlled_execution( ) 下,太累赘。

def controlled_execution(callback):
    set things up
    try:
        callback(thing)
    finally:
        tear things down
 
def my_function(thing):
    do something
 
controlled_execution(my_function)

 

(3) 另一个办法是使用生成器,但是只需要生成一次数据,我们用for-in结构去调用他:

def controlled_execution():  //因为thing只有一个,所以yield语句只需要执行一次,从代码可读性也就是优雅的角度来说这简直是糟糕透了
    set things up
    try:
        yield thing  //--> see "yield"
    finally:
        tear things down
         
for thing in controlled_execution():
    do something with thing

 

(4) with-as新方案

class controlled_execution:
    def __enter__(self):
        set things up
        return thing
    def __exit__(self, type, value, traceback):
        tear things down
         
with controlled_execution() as thing:
        do something

当python执行这一句时,会调用__enter__函数,然后把该函数return的值传给as后指定的变量。之后,python会执行下面do something的语句块。最后不论在该语句块出现了什么异常,都会在离开时执行__exit__。

另外,__exit__除了用于tear things down,还可以进行异常的监控和处理,注意后几个参数。要跳过一个异常,只需要返回该函数True即可。

 

在python2.5及以后,file对象已经写好了__enter____exit__函数,我们可以这样测试:

>>> f = open("x.txt")
>>> f
<open file x.txt, mode r at 0x00AE82F0>
>>> f.__enter__()
<open file x.txt, mode r at 0x00AE82F0>
>>> f.read(1)
X
>>> f.__exit__(None, None, None)
>>> f.read(1)
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>

 

之后,我们如果要打开文件并保证最后关闭他,只需要这么做:

with open("x.txt") as f:
    data = f.read()
    do something with data

 

如果有多个项,我们可以这么写:

with open("x.txt") as f1, open(xxx.txt) as f2:
    do something with f1,f2

 

上文说了__exit__函数可以进行部分异常的处理,如果我们不在这个函数中处理异常,他会正常抛出,这时候我们可以这样写(python 2.7及以上版本,之前的版本参考使用contextlib.nested这个库函数):

try:
    with open( "a.txt" ) as f :
        do something
except xxxError:
    do something about exception

 

总之,with-as表达式极大的简化了每次写finally的工作,这对保持代码的优雅性是有极大帮助的。

 

 

1.1 yield


 From: http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/

  
清单 1. 简单输出斐波那契數列前 N 个数
 def fab(max): 
    n, a, b = 0, 0, 1 
    while n < max: 
        print b         // 不太好! 其实改为yield就好了。
        a, b = b, a + b 
        n = n + 1

执行 fab(5),我们可以得到如下输出:

 >>> fab(5) 
 1 
 1 
 2 
 3 
 5

结果没有问题,但有经验的开发者会指出,直接在 fab 函数中用 print 打印数字会导致该函数可复用性较差,因为 fab 函数返回 None,其他函数无法获得该函数生成的数列。

要提高 fab 函数的可复用性,最好不要直接打印出数列,而是返回一个 List。

 

以下是 fab 函数改写后的第二个版本:

清单 2. 输出斐波那契數列前 N 个数第二版
 def fab(max): 
    n, a, b = 0, 0, 1 
    L = [] 
    while n < max: 
        L.append(b) 
        a, b = b, a + b 
        n = n + 1 
    return L       // 暂用内存太大!

可以使用如下方式打印出 fab 函数返回的 List:

 >>> for n in fab(5): 
 ...     print n 
 ... 
 1 
 1 
 2 
 3 
 5

改写后的 fab 函数通过返回 List 能满足复用性的要求,但是更有经验的开发者会指出,该函数在运行中占用的内存会随着参数 max 的增大而增大。

 

如果要控制内存占用,最好不要用 List来保存中间结果,而是通过 iterable 对象来迭代。例如,在 Python2.x 中,代码:

清单 3. 通过 iterable 对象来迭代
for i in range(1000): pass  //会导致生成一个 1000 个元素的 List

for i in xrange(1000): pass // iterable对象是解决的办法!

在每次迭代中返回下一个数值,内存空间占用很小。因为 xrange 不返回 List,而是返回一个 iterable 对象。

 

利用 iterable 我们可以把 fab 函数改写为一个支持 iterable 的 class,以下是第三个版本的 Fab:

清单 4. 第三个版本
 class Fab(object): 

    def __init__(self, max): 
        self.max = max 
        self.n, self.a, self.b = 0, 0, 1 

    def __iter__(self): 
        return self 

    def next(self): 
        if self.n < self.max: 
            r = self.b 
            self.a, self.b = self.b, self.a + self.b 
            self.n = self.n + 1 
            return r 
        raise StopIteration()

Fab 类通过 next() 不断返回数列的下一个数,内存占用始终为常数:

 >>> for n in Fab(5): 
 ...     print n 
 ... 
 1 
 1 
 2 
 3 
 5

然而,使用 class 改写的这个版本,代码远远没有第一版的 fab 函数来得简洁。

 

如果我们想要保持第一版 fab 函数的简洁性,同时又要获得 iterable 的效果,yield 就派上用场了:

清单 5. 使用 yield 的第四版
 def fab(max): 
    n, a, b = 0, 0, 1 
    while n < max: 
        yield b 
        # print b 
        a, b = b, a + b 
        n = n + 1 

第四个版本的 fab 和第一版相比,仅仅把 print b 改为了 yield b,就在保持简洁性的同时获得了 iterable 的效果。

调用第四版的 fab 和第二版的 fab 完全一致:

 >>> for n in fab(5):   // for执行一次函数,其实只是调用了函数内的一次运算;再调一次就再继续算一次!
 ...     print n 
 ... 
 1 
 1 
 2 
 3 
 5
 

也可以手动调用 fab(5) 的 next() 方法(因为 fab(5) 是一个 generator 对象,该对象具有 next() 方法),这样我们就可以更清楚地看到 fab 的执行流程:

清单 6. 执行流程
 >>> f = fab(5)  // fab(5) 是iterable function,这里就是指的fab的实例
 >>> f.next()    // 与清单4 中的next比较下,其实是相同的思想
 1 
 >>> f.next() 
 1 
 >>> f.next() 
 2 
 >>> f.next() 
 3 
 >>> f.next() 
 5 
 >>> f.next() 
 Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
 StopIteration

当函数执行结束时,generator 自动抛出 StopIteration 异常,表示迭代完成。在 for 循环里,无需处理 StopIteration 异常,循环会正常结束。

 

 

 

2. exec


 From: http://blog.sina.com.cn/s/blog_76e94d210100w1bl.html

 

exec语句用来执行储存在字符串文件中的Python语句

例如,我们可以在运行时生成一个包含Python代码的字符串,然后使用exec语句执行这些语句。

下面是一个简单的例子。

>>> exec print "Hello World"
Hello World

 

eval语句用来计算存储在字符串中的有效Python表达式。下面是一个简单的例子。

>>> eval_r(2*3)
6

eval_r(str [ globals [ locals ]])函数将字符串str当成有效python表达式来求值,并返回计算结果。

同样地, exec语句将字符串str当成有效Python代码来执。.提供给exec的代码的名称空间和exec语句的名称空间相同。

最后,execfile(filename [, globals [, locals ]]) 函数可以用来执行一个文件。


>>> eval_r(3+4)
7
>>> exec a=100 
>>> a 
100 
>>> execfile(rd:\code\ex\test.py)
hello world!
>>>

默认的,eval_r(), exec, execfile() 所运行的代码都位于当前的名字空间中.

eval_r(), exec 和 execfile()函数 也可以接受一个或两个可选字典参数作为代码执行的全局名字空间局部名字空间。

 

 

 

2.1 Python命名空间和作用域


From: http://blog.cipherc.com/2015/04/25/python_namespace_and_scope/#assignment-rule

 

 

 

[Python] Symbol Review

标签:

原文地址:http://www.cnblogs.com/jesse123/p/5624664.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!