Python一些高级的东西

  • 闭包: 在Python中,所谓的闭包是一个包含有环境变量取值的函数对象. 环境变量取值被保存在函数对象的__closure__属性中。那什么是环境变量呢?直接看代码吧. 
def line_conf(a): 
    b = 15
    def line(x):
        return 2*x+b
    return line       # return a function object

#对于函数line来说, a,b就是它的环境变量.
#环境变量可以看成超出它的函数作用域却还能访问到的对象
  • 装饰器: 闭包的应用.
paths = {}

def query(path):

    if path in paths: return paths['path']
    
    def deco(func):

        paths['path'] = func
        
        def _deco(*args, **kwargs):
            return func(*args, **kwargs)
        
        return _deco
    return deco

@query('login')
def login(a):
    print a

#最终执行的是装饰器的返回函数
login('a')
  •  迭代器: 

    迭代器是访问集合内元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素都被访问一遍后结束。

    迭代器不能回退,只能往前进行迭代。这并不是什么很大的缺点,因为人们几乎不需要在迭代途中进行回退操作。

    迭代器也不是线程安全的,在多线程环境中对可变集合使用迭代器是一个危险的操作。但如果小心谨慎,或者干脆贯彻函数式思想坚持使用不可变的集合,那这也不是什么大问题。

    对于原生支持随机访问的数据结构(如tuple、list),迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值,这是后话)。但对于无法随机访问的数据结构(比如set)而言,迭代器是唯一的访问元素的方式。

    迭代器的另一个优点就是它不要求你事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。这个特点被称为延迟计算或惰性求值(Lazy evaluation)。

    迭代器更大的功劳是提供了一个统一的访问集合的接口。只要是实现了__iter__()方法的对象,就可以使用迭代器进行访问。

   实际上,因为迭代操作如此普遍,Python专门将关键字for用作了迭代器的语法糖。在for循环中,Python将自动调用工厂函数iter()获得迭代器,自动调用next()获取元素,还完成了检查StopIteration异常的工作。上述代码可以写成如下的形式,你一定非常熟悉:

for val in lst:
    print val
for index, element in enumerate(lst): #获得索引和当前元素
    print index, element
  • 生成器表达式(Generator expression)和列表解析(List Comprehension)
(x+1 for x in lst if x>0) #生成器表达式,返回迭代器。外部的括号可在用于参数时省略。 
[x+1 for x in lst] #列表解析,返回list

  生成器表达式和列表解析(注:这里的翻译有很多种,比如列表展开、列表推导等等,指的是同一个意思)的区别很小,所以人们提到这个特性时,简单起见往往只描述成列表解析。然而由于返回迭代器时,并不是在一开始就计算所有的元素,这样能得到更多的灵活性并且可以避开很多不必要的计算,所以除非你明确希望返回列表,否则应该始终使用生成器表达式。

  • 生成器(Generator)

  首先请确信,生成器就是一种迭代器。生成器拥有next方法并且行为与迭代器完全相同,这意味着生成器也可以用于Python的for循环中。另外,对于生成器的特殊语法支持使得编写一个生成器比自定义一个常规的迭代器要简单不少,所以生成器也是最常用到的特性之一。

def get_0_1_2():
    yield 0
    yield 1
    yield 2

  生成器的运行顺序: 每次调用,就会一直运行直到遇到了 yield 关键字, 返回yield的参数. 此时暂停执行时,函数体内的所有变量都将被封存(freeze)在生成器中. 当再次调用时, 从上次暂停的地方开始运行,知道再次遇到 yield 才会再次挂起.

引用自:

闭包:  http://www.cnblogs.com/vamei/archive/2012/12/15/2772451.html

装饰器:http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html

生成器:http://www.cnblogs.com/huxi/archive/2011/07/14/2106863.html

迭代器:http://www.cnblogs.com/huxi/archive/2011/07/01/2095931.html

本文记录以上文章的重点(个人观点)

原文地址:https://www.cnblogs.com/lanxue/p/2942420.html