Python学习笔记(三)

1. 函数式编程

1. 高阶函数

  1. 变量可以指向函数

    1. >>> f = abs
    2. >>> f(-10)
    3. 10
  2. 函数名也是变量
  3. 传入函数

    1. def add(x, y, f):
    2. return f(x) + f(y)
    3. >>> add(-5, 6, abs)
    4. 11

1. map/reduce

  1. map()
    map()函数接收两个参数,分别是函数和Iterable。map将传入的参数分别作用到序列的每个元素,并把结果作为新的Iterator返回。

    1. >>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
    2. ['1', '2', '3', '4', '5', '6', '7', '8', '9']
  2. reduce()
    reduce()是把一个函数作用在一个序列[x1,x2,x3…]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算。

    1. >>> from functools import reduce
    2. >>> def add(x, y):
    3. ... return x + y
    4. ...
    5. >>> reduce(add, [1, 3, 5, 7, 9])
    6. 25

    str转化成int:

    1. >>> from functools import reduce
    2. >>> def fn(x, y):
    3. ... return x * 10 + y
    4. ...
    5. >>> def char2num(s):
    6. ... return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
    7. ...
    8. >>> reduce(fn, map(char2num, '13579'))
    9. 13579

2. filter

filter()函数用于过滤序列。filter也接收一个函数和一个序列,filter()把传入的函数依次作用于每个元素,然后根据返回值是true或false决定保留还是丢弃该元素。

  1. def is_odd(n):
  2. return n % 2 == 1
  3. list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
  4. [1, 5, 9, 15]

3. sorted

Python内置的sorted()能对lsit函数进行排序。
sorted()函数也是一个高阶函数,可以接收一个key函数来实现自定义的排序。

  1. >>> sorted([36, 5, -12, 9, -21], key=abs)
  2. [5, 9, -12, -21, 36]

2. 返回函数

高阶函数除了可以接受参数作为参数外,还可以把函数作为结果值返回。

  1. def lazy_sum(*args):
  2. def sum():
  3. ax = 0
  4. for n in args:
  5. ax = ax + n
  6. return ax
  7. return sum

当调用lazy_sum()时返回的并不是求和结果,而是求和函数。
在函数lazy_sum()中又定义了函数sum(),并且,内部函数sum可以调用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存到返回的函数中,这种程序结构称为”毕包“。
当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数。返回函数不要引入任何循环变量,或者后续发生变化的变量。

3. 匿名函数

  1. >>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
  2. [1, 4, 9, 16, 25, 36, 49, 64, 81]

关键字lambda表示匿名函数,冒号前面的x表示函数参数。匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数,同样也可以把匿名函数作为返回值返回。

  1. def build(x, y):
  2. return lambda: x * x + y * y

4. 装饰器

函数对象有一个”_name_”属性,可以拿到函数的名字。
在代码运行期间动态增加功能的方式,称之为“装饰器(Decorator)”。

  1. def log(func):
  2. def wrapper(*args, **kw):
  3. print('call %s():' % func.__name__)
  4. return func(*args, **kw)
  5. return wrapper
  1. @log
  2. def now():
  3. print('2015-3-25')
  1. >>> now()
  2. call now():
  3. 2015-3-25

wrapper()参数的函数定义是(args,*kw),因此,wrapper()函数可以接受任意参数的调用,在wrapper()函数内,首先打印日志,再紧接着调用原始函数。

5. 偏函数

int()函数提供额外的base参数,默认值是10。如果传入base参数,就可以做N进制的转换。

  1. >>> import functools
  2. >>> int2 = functools.partial(int, base=2)
  3. >>> int2('1000000')
  4. 64
  5. >>> int2('1010101')
  6. 85

functools.partial(int,base=2)的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新函数,调用这个函数会更加简单。

2. 模块

为了编写可维护的代码,我们把很多函数分组,分别放在不同的文件夹里,这样,每个文件夹含的代码相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就称之为一个模块
为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为(Package)。每一个包目录下面都会有一个_init_.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。

1. 使用模块

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. ' a test module '
  4. __author__ = 'Michael Liao'
  5. import sys
  6. def test():
  7. args = sys.argv
  8. if len(args)==1:
  9. print('Hello, world!')
  10. elif len(args)==2:
  11. print('Hello, %s!' % args[1])
  12. else:
  13. print('Too many arguments!')
  14. if __name__=='__main__':
  15. test()

当我们在dos运行hello模块文件时,Python解释器会把特殊变量_name_置为_main_,而如果在其他地方导入该模块时,if判断将会失败。
作用域:
在Python中,通过_前缀来区分public和private。

  1. 正常的函数和变量名是公开的,可以直接被访问。
  2. 类似_xxx_这样的变量是特殊变量,可以被直接引用,但是有特殊的用途。我们自己的变量一般不使用这种变量名。
  3. 类似_xxx这样的函数或变量就是非公开的,不应该被直接引用。一般使用greeting()函数(类似Java的get())。

2. 安装第三方模块

在Python中,安装第三方模块,是通过包管理工具pip完成的。

  1. pip install Pillow # Pillow是Python下非常强大的处理图像的工具库

模块搜索路径:
当我们试图加载一个模块时,Python会在指定的路径下搜索对应的.py文件,如果找不到就会报错。默认情况下,Python解释器会搜索当前目录,所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中。
如果我们要添加自己的搜索目录,有两种方法:

  1. 直接修改sys.path
  2. 设置环境变量PYTHONPATH




posted @ 2016-06-01 15:46  ldbmcs  阅读(387)  评论(0编辑  收藏  举报