11章 函数/函数式编程
Posted 小阿Q的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了11章 函数/函数式编程相关的知识,希望对你有一定的参考价值。
1.函数
在python中,函数通过def关键字、函数名和可选的参数列表定义。通过return关键字返回值。
2.函数参数
在Python中函数的参数可以是必须的位置参数或者是关键字参数(默认参数)
>>> def foo(x, y = 1): return x-y >>> foo(3,2) 1 >>> foo(3) 2 >>>
3 传递函数
所以对象都是通过引用来传递,函数也不例外,当对一个变量赋值时,实际是将相同对象的引用赋值给这个变量,如果对象是函数的话,这个对象所有的别名都是可以调用。
>>> def foo(): print ‘in foo()‘ >>> foo() in foo() >>> bar = foo >>> bar() in foo()
foo()函数对象的调用, foo函数对象的引用
4 嵌套函数
Python允许创建嵌套函数。。
def outer(): x = 1 def inner(): print x # 1 inner() # 2 outer() 1
python解释器需找一个叫x的本地变量,查找失败之后会继续在上层的作用域里面寻找,这个上层的作用域定义在另外一个函数里面。对函数outer来说,变量x是一个本地变量,函数inner可以访问封闭的作用域,调用函数inner,inner也仅仅是一个遵循python变量解析规则的变量名,Python解释器会优先在outer的作用域里面对变量名inner查找匹配的变量.
5.闭包
该处摘自 "http://python.jobbole.com/81683/" 对闭包解释很到位
>>> def outer(): x = 1 def inner(): print x #1 return inner >>> foo = outer() >>> foo.func_closure (<cell at 0x01BB5F30: int object at 0x012D7D20>,) >>> foo <function inner at 0x01BB8DF0> >>> foo() 1
python的作用域规则下:x是函数outer里的一个局部变量。当函数inner在#1处打印x的时候,python解释器会在inner内部查找相应的变量,当然会找不到,所以接着会到封闭作用域里面查找,并且会找到匹配。
但是从变量的生存周期来看,我们的变量x是函数outer的一个本地变量,这意味着只有当函数outer正在运行的时候才会存在。根据我们已知的python运行模式,我们没法在函数outer返回之后继续调用函数inner,在函数inner被调用的时候,变量x早已不复存在,可能会发生 一个运行时错误。但万万没想到,返回的函数inner居然能够正常工作。Python支持一个叫做函数闭包的特性,用人话来讲就是,嵌套定义在非全局作用域里面的函数 能够记住它在被定义的时候它所处的封闭命名空间。这能够通过查看函数的func_closure属性得出结论,这个属性里面包含封闭作用域里面的值(只会 包含被捕捉到的值,比如x,如果在outer里面还定义了其他的值,封闭作用域里面是不会有的)。
每次函数outer被调用的时候,函数inner都会被重新定义
def outer(x): def inner(): print x return inner >>> a = outer(1) >>> b = outer(2) >>> a() 1 >>> b() 2 >>>
6 装饰器
装饰器就是闭包的体现,是在函数调用上的修饰
def outer(some_func): def inner(): print "before some_func" ret = some_func() # 1 return ret + 1 return inner def foo(): return 1 decorated = outer(foo) # 2 decorated() before some_func 2
上面这个装饰器的例子。定义了一个函数outer,它只有一个some_func的参数,在里面定义了一个嵌套的函数inner。 inner会打印一串字符串,然后调用some_func,在#1处得到它的返回值。在outer每次调用的时候some_func的值可能会不一样,但是不管some_func的之如何,最终都会调用它。最后,inner返回some_func() + 1的值,通过调用在#2处存储在变量decorated里面的函数能够看到被打印出来的字符串以及返回值2,而不是期望中调用函数foo得到的返回值1。
装饰器的语法是以@开始,接着是装饰器函数的名字和可选参数。紧跟着装饰器声明的是修饰的函数和装饰器的可选参数。
def timeTest(func): def test(): start = time.clock() func() end = time.clock() print end-start return test @timeTest def foo(): print ‘foo()‘ foo()
关于装饰器,后续新增一篇详细介绍
以上是关于11章 函数/函数式编程的主要内容,如果未能解决你的问题,请参考以下文章