第11章 函数和函数式编程(5)

11.7.3 偏函数应用

Currying能泛化成为偏函数应用(partial function application, PFA),这种函数将任意数量(顺序)的参数的函数转化成另一个带剩余参数的函数对象。

1. 简单的函数式例子

>>> from functools import partial
>>> intbase2 = partial(int, base = 2)
>>> intbase2("1010100010101010101010")
2763434
>>>

2. 警惕关键字

如果你创建了不带base关键字的偏函数,比如baseTwo-BAD = partial(int, 2),这可能会让参数以错误的顺序传入int(),因为固定参数的总是放在运行时刻参数的左边。

11.8 变量作用域

11.8.1 全局变量与局部变量

定义在函数内的变量有局部作用域,在一个模块中最高级别的变量有全局作用域。

全局变量的一个特征是除非被删除掉,否则它们的存活到脚本运行结束,且对于所有的函数,他们的值都是可以被访问的,然而局部变量,就像它们存放的栈,暂时地存在,仅仅只依赖于定义它们的函数现阶段是否处于活动。当一个函数调用出现时,其局部变量名为那个对象创建了,一旦函数完成,框架被释放,变量将会离开作用域。

>>> global_str = 'foo'
>>> def foo():
... local_str = 'bar'
... return global_str + local_str
...
>>>

当搜索一个标识符的时候,Python先从局部作用域开始搜索。如果在局部作用域内没有找到这个名字时,那么就一定会在全局域找到这个变量否则就会被抛出NameError异常。

仅仅通过创建一个局部变量来“隐藏”或者覆盖一个全局变量是有可能的。

如果在赋予局部变量值之前,你在函数中使用了这样的名字,你将会得到一个异常。

>>> global_str = 'foo'
>>> def foo2():
... global_str = 'bar'
... return global_str
...
>>> foo2()
'bar'
>>> def foo3():
... global_str
... print global_str
... global_str = 'bar'
... return global_str
...
>>> foo3()
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "<interactive input>", line 2, in foo3
UnboundLocalError: local variable 'global_str' referenced before assignment
>>>

11.8.2 global语句

为了明确地引用一个已命名的全局变量,必须使用global语句。global的语法如下:

global var1[, var2[, ...varN]]


>>> global_str = "GlobalSet"
>>> def foo():
... global global_str
... global_str = "LocalSet"
...
>>> print global_str
GlobalSet
>>> foo()
>>> print global_str
LocalSet
>>>

11.8.4 闭包

如果在一个内部函数里,对在外部作用域的变量进行引用,那么内部函数就被认为是闭包(closure)。定义在外部函数内的但由内部函数引用或者使用的变量称为自由变量。

闭包对于安装计算、隐藏状态和在函数对象和作用域中随意地切换是很有用的。

1.简单的闭包的例子

>>> def counter(start_at = 0):
... count = [start_at]
... def incr():
... count[0] +=1
... return count[0]
... return incr
...
>>> count1 = counter()
>>> count1()
1
>>>

11.8.5 作用域和lambda

那些声明为函数局部变量的lambda表达式在这个函数内是可以访问的;然而,在lambda语句中的表达式有和函数相同的作用域。你也可以认为函数和一个lambda表达式是同胞。

lambda表达式在foo()的局部作用域中创建,但它仅仅只能访问两个作用域:它自己的局部作用域和全局的作用域。

>>> def foo():
... y = 5
... bar = lambda y: x+y
... print bar(y)
... y = 9
... print bar(y)
...
>>> foo()
15
19
>>>

10.8.6 变量作用域和名称空间

>>> j, k = 1, 2
>>> def procl():
... j, k = 3, 4
... print j,' ', k
... k = 5
...
>>> def procl2():
... j = 6
... procl()
... print j,' ', k
...
>>> k = 7
>>> procl()
3 4
>>> print j, ' ', k
1 7
>>> j = 8
>>> procl2()
3 4
6 7
>>> print j, ' ', k
8 7
>>>


你可能感兴趣的:(函数式编程)