天天看点

Python知识6 函数式编程和装饰器【多测师】

一、函数式编程之高阶函数
print(abs(-10))
结果:10
<built-in function abs> —abs(-10)是函数调用 abs是函数本身
获得函数调用的结果 可以把结果赋值给变量
x=abs(-13)
print(x)
结果:13
把函数本身赋值给变量
x=abs
print(x)
<built-in function abs>—-结论:函数本身可以赋值给变量 变量可以指向函数

通过该变量来调用这个函数
x=abs
print(x(-12))
结论:变量x已经指向了abs函数本身 直接调用abs()函数和调用变量x()完全相同

二、函数名 —函数名也是变量
1.函数名就是指向函数的变量 把abs看成变量 它指向一个可以计算绝对值的函数
2.abs函数定义在import builtins模块当中

三、函数可以指向变量 (高阶函数)
1.举例一个简单的高阶函数
def add(x,y,a):
    return a(x)+a(y)

print(add(1,-2,abs))
结果:3

四、高阶函数之map/reduce
1.Python內建的函数
2.代码实现:
def f(x):
    return x*x

r=map(f,[1,2,3,4,5])
print(list(r))
3.不用map()函数 直接写一个循环来进行计算
def f(x):
    return x*x

L=[]
for n in [1,2,3,4,5]:
    L.append(f(n))

print(L)
4.reduce 求一个序列的和
from functools import reduce

def add(x,y):
    return x+y

print(reduce(add,[1,3,5,7,9]))
运行结果:25
5.reduce內建函数
from functools import reduce

def fn(x,y):
    return x*10+y

print(reduce(fn,[1,3,5,7,9]))

五、高阶函数之filter
1.python內建filter()函数用于过滤序列
根据返回值的true和false 决定是否保留或丢弃该元素
def is_odd(n):
    return n%2 == 1

print(list(filter(is_odd,[1,3,5,8,19])))
结果:[1, 3, 5, 19]
2.把序列的空字符串删除
def no_empty(s):
    return s and s.strip()

print(list(filter(no_empty,['A','','B',None,'C',''])))
3.用filter求素数
def _odd_iter():
    n = 1
    while True:
        n = n+2
        yield n

def _not_divisible(n):
    return lambda x:x%n>0

def primas():
    yield 2
    it =_odd_iter()
    while True:
        n = next(it)
        yield n
        it = filter(_not_divisible(n),it)

for n in primas():
    if n <1000:
        print(n)
    else:
        break

六、高阶函数之sorted
1.排序算法 sorted排序
print(sorted([36,12,3,6,91]))
2.按绝对值排序 接受一个key函数实现自定义排序
print(sorted([-12,4,7,19,-1],key=abs))
3.字典串排序 传入key值可以忽略字母的大小写进行排序
print(sorted(['bob','about','zoo','credit'],key=str.lower))
4.倒叙排序 加上reverse=True
print(sorted(['bob','about','zoo','credit'],key=str.lower,reverse=True))

七、返回函数
1.返回函数:函数作为返回值
def lazy_num(*args):  #在lazy_num中定义了函数sum 内部函数sum可以引用外部函数
    def sum():        #lazy_num的参数和局部变量
        ax = 0
        for n in args:
            ax=ax+n
        return ax
    return sum

p1=lazy_num(1,2,7,12,13)
p2=lazy_num(87,34,1,41)
print(p1())
print(p2())

2.什么叫闭包?
就是在一个函数里面定义了一个新的函数,这个新的内部函数可以引用外部函数的参数和局部变量,当外部函数返回内部函数的时候,相关的参数和变量都保存在返回的参数中这种就称为闭包。。。
3.接上面 返回的函数在其定义内部引用了局部变量args 当一个函数返回一个函数后 其内部的局部变量被新函数引用,而且要用p1()调用 直接用p1是调用不了的

八、匿名函数
1.以map()函数为例,计算f(x)=x2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数:
list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
2.匿名函数lambda x: x * x实际上就是:
def f(x):
    return x * x

3. 关键字lambda表示匿名函数,冒号前面的x表示函数参数。匿名函数只能有一个表达式 不用写return 返回值就是该表达式的结果
4.匿名函数式一个函数对象,可以把匿名函数赋值给一个变量 再利用变量来调用该函数
>>> f = lambda x: x * x
>>> f
<function <lambda> at 0x101c6ef28>
>>> f(5)
25
5.也可以把匿名函数作为返回值返回
def build(x, y):
    return lambda: x * x + y * y

九、装饰器
1.装饰器:函数也是一个对象 且函数对象可以被赋值给变量 所以变量也能调用该函数
>>> def now():
...     print('2015-3-25')
...
>>> f = now
>>> f()
2015-3-25
2.函数对象有一个__name__属性,可以拿到函数的名字
>>> now.__name__
'now'
>>> f.__name__
'now'
3.装饰器(Decorator):假设要增强now()函数的功能,又不希望修改now()函数的定义 这种在代码运行期间动态增加功能的方式称为:装饰器(Decorator)

代码如下:
def log(func):
    def wrapper(*args,**kw):
        print('call %s:' % func.__name__)
        return func(*args,**kw)
    return wrapper

@log
def now():
    print('2018-05-08')

now()

十、偏函数
1.通过设定参数的默认值,降低函数调用的难度
int()函数可以把字符串转换为整数
>>> int('12345') ---int()函数默认按十进制转换
12345
print(int('12345',base=8)) ---传入base参数 可以做2-36进制转换
2.转换大量的二进制字符串
def int2(x,base=2):
    return int(x,base)

print(int2('1000000'))
3.创建偏函数 实际上固定了int()函数的关键字参数base
import functools

int2=functools.partial(int,base=2)
print(int2('10101'))
4.args=(10,5,6,7,)
print(max(*args))