首页 > 代码库 > 11章 函数/函数式编程

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 innerdef foo():     return 1decorated = outer(foo) # 2decorated()before some_func2

上面这个装饰器的例子。定义了一个函数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@timeTestdef foo():    print ‘foo()‘foo()

关于装饰器,后续新增一篇详细介绍

11章 函数/函数式编程