python 核心编程 第十章

函数,函数。

为什么使用函数?

  1. 利于代码的再次利用,不然各种复制也是醉。
  2. 改变程序逻辑,简单的说就是吧代码分成一块一块的,逻辑比较清晰。

函数的特性

  1. 返回值可以为空,也可以返回一个列表或者元组。如果没有return,返回值是None。
  2. 使用.__doc__可以调用函数的说明文档。
  3. 可变长参数:使用* 和**。可允许函数接受函数声明定义的形参之外的参数

参数的传递:

  1. 关键字参数:就是为了用名字来区分参数
  2. 默认参数:预先指定参数的值。
  3. 参数组:把字典,元组或者列表当成参数传给函数。
  4. 传递函数:可以将函数作为参数传递,并在另一个函数内调用函数。

装饰器

  1. 什么是装饰器:定义是函数之上的装饰
    说实话,感觉python核心编程讲的太笼统读不太懂。廖雪峰的教程是这样描述的:
    希望增强函数的功能,但又不希望改变原函数的定义,这种在代码运行期间动态增加功能的方法就称为“装饰器”
    ps:还是无法理解装饰器的意义在哪里,装饰器使原来的函数调用指向了另一个高级函数,而原函数并没有改变但无法访问,这个有什么用呢。这个以后碰到用处再继续看。

可变长度的参数

  1. 函数中使用* 和**来指定元组和字典的元素作为非关键字和关键字参数。
  2. 关键字字典必须为最后一个参数并且非关键字元组要先于他之前
def newfoo(arg1, arg2, *nkw, **kw):
    print"arg1 is:",arg1
    print"arg2 is:", arg2
    for i in nkw:
        print"additional non-keyword arg:",i
    for j in kw.keys():
        print"additional keyword arg'%s:'%s"%(j,kw[j])
newfoo("wolf",3,'projects',freud=90,gamble=96)
  1. 还可以把非关键字放在元组中,关键字参数放在字典中进行调用。

函数式编程内建函数:

  1. filter(func, seq)b
    调用一个布尔函数 func 来迭代遍历每个 seq 中的元素; 返回一个使 func 返回值为 ture 的元素的序列。
  2. map(func, seq1[,seq2...])b
    将函数 func 作用于给定序列(s)的每个元素,并用一个列表来提供返回值;如果 func 为 None, func 表现为一个身份函数,返回一个含有每个序列中元素集合的 n 个元组的列表。
  3. reduce(func, seq[, init])
    将二元函数作用于 seq 序列的元素,每次携带一对(先前的结果以及下一个序列元素) ,连续的将现有的结果和下雨给值作用在获得的随后的结果上,最后减少我们的序列为一个单一的返回值;如果初始值 init 给定,第一个比较会是 init 和第一个序列元素而不是序列的头两个元素。

偏函数

其实很容易理解,就是使函数直接使用默认函数,使用funtools模块里面的partial函数直接固定函数的参数
例如

from functools import partial
import Tkinter
root = Tkinter.Tk()
MyButton = partial(Tkinter.Button, root, fg="white", bg="blue")
b1 = MyButton(text="Button 1")
b2 = MyButton(text="Button 2")
qb =MyButton(text="Quit",bg="red", command=root.quit)
b1.pack()
b2.pack()
qb.pack(fill=Tkinter.X, expand=True)
root.title("PFAs!")
root.mainloop()

其中 partial(Tkinter.Button, root, fg="white", bg="blue")的效果就是,直接把Tkinter.Button函数,固定传入的三个参数。

变量的作用域

  1. 全局变量会一直存在,而局部变量在所在函数调用完成后就无法访问了。
  2. 访问变量首先会查找局部变量名若没有,接着才查找全局变量,使用globa可以直接明确函数调用的是全局变量。
  3. 对于函数的嵌套,不能访问超过两个作用域。

闭包

直接上例子吧

def counter(start_at=0):
    count = [start_at]
    def incr():
        count[0] +=1
        return count[0]
    return incr
count = counter(5)
print count()
print count()
count2 = counter(100)
print count2()
print count()

练习

11–7. 用 map() 进 行 函 数 式 编 程 。 给 定 一 对 同 一 大 小 的 列 表 , 如 [1 , 2 , 3] 和
['abc','def','ghi',....],将两个标归并为一个由每个列表元素组成的元组的单一的表,以使我
们的结果看起来像这样:{[(1, 'abc'), (2, 'def'), (3, 'ghi'), ...}.(虽然这问题在本质上和
第六章的一个问题相似,那时两个解没有直接的联系)然后创建用 zip 内建函数创建另一个解。

map(lambda x, y: (x, y), [1,2,3],["abc", "def", "ghi"])
zip([1, 2, 3], ["abc", "def", "ghi"])

11–9. 用 reduce()进行函数式编程。复习 11.7.2 部分,阐述如何用 reduce()数字集合的累
加的代码。修改它,创建一个叫 average()的函数来计算每个数字集合的简单的平均值。
def average(args):
return reduce(lambda x, y: x+y, args)/float(len(args))
print average(range(2))

posted @ 2016-10-21 23:41  即刻  阅读(261)  评论(0编辑  收藏  举报