1. 函数式编程1. 高阶函数
1. map/reduce
2. filter
3. sorted
2. 返回函数
3. 匿名函数
4. 装饰器
5. 偏函数
2. 模块
1. 使用模块
2. 安装第三方模块

1. 函数式编程

1. 高阶函数

  1. 变量可以指向函数
>>> f = abs
>>> f(-10)
10
  1. 函数名也是变量
  2. 传入函数
def add(x, y, f):
return f(x) + f(y)
>>> add(-5, 6, abs)
11

1. map/reduce

  1. map()
    map()函数接收两个参数,分别是函数和Iterable。map将传入的参数分别作用到序列的每个元素,并把结果作为新的Iterator返回。
>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
  1. reduce()
    reduce()是把一个函数作用在一个序列[x1,x2,x3…]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算。
>>> from functools import reduce
>>> def add(x, y):
...     return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25

str转化成int:

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

2. filter

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

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

3. sorted

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

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

2. 返回函数

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

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum

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

3. 匿名函数

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

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

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

4. 装饰器

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

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

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

5. 偏函数

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

>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85

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

2. 模块

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

1. 使用模块

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

' a test module '

__author__ = 'Michael Liao'

import sys

def test():
    args = sys.argv
    if len(args)==1:
            print('Hello, world!')
    elif len(args)==2:
        print('Hello, %s!' % args[1])
    else:
        print('Too many arguments!')

if __name__=='__main__':
    test()

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

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

2. 安装第三方模块

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

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

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

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