第七章 函数式编程

7.1又见函数

1.python中的函数式

函数式编程以函数为中心进行代码封装。函数式编程强调了函数的纯粹性。一个纯函数是没有副作用的,即这个函数的运行不会影响其他函数。进程的先后顺序不同会影响最终结果,这被称为竞跑条件,函数式编程消灭了副作用,即无形中消除了竞跑条件的可能。

2.并行运算

所谓的并行运算是指多条指令同时执行。一个程序运行后,就成为一个进程,进程有自己的内存空间,用来储存自身的运行状态、数据和相关代码。一个进程内部又可以有多个称为“线程”的任务,处理器可以在多个线程之间切换,从而形成并行的多线程处理。线程之间可以共享同一个进程的内存空间。

7.2被解放的函数

1.函数作为参数和返回值

def square_sum(a,b):

    return a**2+b**2

def cubic_sum(a,b):

    return a**3+b**3

def argument_demo(f,a,b):

    return f(a,b)

print(argument_demo(square_sum,3,5))

print(argument_demo(cubic_sum,3,5))

2.函数作为返回值

def line_conf():

    def line(x):

        return 2*x+1

    return line

my_line=line_conf()

print(my_line(5))#打印11

我们在line_conf()函数的隶属范围内定义的函数line(),就只能在line_conf()的隶属范围内调用。

3.闭包

def line_conf():

    b=15

    def line(x):

        return 2*x+b#闭包

    b=5

    return line

if __name__=="__main__":

    my_line=line_conf() 

    print(my_line(5))#打印15

line()定义的隶属程序块中引用了高层及的变量b。b的定义并不在line()内部,而是一个外部的对象。我们称b为line()的环境变量。尽管b位于line()定义的外部,但当line被函数line_conf()返回时,还是会带有b的信息。一个函数和他的环境变量组合在一起,就构成了一个闭包。在python中,所谓闭包是一个包含环境变量取值的函数对象。

闭包可以提升代码的复用性:

def line_conf(a,b):

    def line(x):

        return a*x+b

    return line

line1=line_conf(1,1)

line2=line_conf(-2,-6)

这个例子中,函数line()与环境变量a、b构成闭包。除了复用代码,闭包还能起到减少函数参数的作用。

7.3小女子的化妆匣

1.装饰器

装饰器可以对一个函数、方法或者类进行加工。

def decorator_demo(old_function):

    def new_function(a,b):

        print("input",a,b)

        return old_function(a,b)

    return new_function

@decorator_demo

def square_sum(a,b):

    return a**2+b**2

if __name__=="__main__":

    print(square_sum(3,4))

定义好装饰器后,我们就可以通过@语法使用了,在函数square_sum()定义之前调用@decorator_demo,实际上是将square_sum()传递给了decorator_demo(),并将decorator_demo()返回的新函数对象赋给原来的函数名square_sum()。

2.带参装饰器

def pre_str(pre=""):

    def decorator(old_function):

        def new_function(a,b):

             print(pre+"input",a,b)

             return old_function(a,b)

        return new_function

    return decorator

@pre_str("^_^")

def square_sum(a,b):

    return a**2+b**2

if __name__ =="__main__":

    print(square_sum(3,4))

3.装饰类

一个装饰器可以接受一个类,并返回一个类,从而起到加工类的效果P180。

7.4高阶函数

1.lambda与map

能接收其他函数作为参数的函数,被称为高阶函数。

lambda:

lambda_sum=lambda x,y:x+y

print(lambda_sum(3,4))

map:

data_list=[1,3,5,6]

result=map(lambda x:x+3,data_list)

map的第一个参数是一个函数对象,第二个参数是一个可循环对象。对于data_list的每个元素,lamdba函数都会调用一次。那个元素会成为lamdba函数的参数。最终,map()会返回一个迭代器。迭代器中的元素,就是多次调用lamdba函数的结果。

这个函数也可以是一个多参数的函数,这时map()的参数列表中就需要提供相应数目的课循环对象。

2.filter函数

如果函数对象返回的是True,则该次的元素被放到返回的迭代器中。

def larger100(a):

    if a>100:

        return True

    else:

        return False

for itemin filter(larger100,[10,56,101,500]):

    print(item)

3.reduce函数

reduce()在标准库中的functools包中,使用之前需要引入。reduce()对作为参数的函数对象有一个特殊要求,就是这个作为参数的函数必须能接收两个参数:

from functoolsimport reduce

data_list=[1,2,5,7,9]

result=reduce(lambda x,y:x+y,data_list)

print(result)#打印24

函数reduce()的第一个参数是求和sum()函数,它接收两个参数x和y。上一次运算的结果将作为下一次调用的第一个参数。

4.并行处理

下载的程序就是在多进程条件下使用了多线程的map()方法。这段进程多线程的下载同一个URL下的资源。程序用了第三方包requests来进行HTTP下载P187。从结果可以看到,运行时间能大为缩短。

7.5自上而下

1.便捷表达式

生成器表达式是构建生成器的便捷方法:

gen=(x for x in range(4))

生成表的快捷方式,列表解析:
l=[x**2 for x in range(10)]

除了for,列表解析中还可以使用if:

xl=[1,3,5]

yl=[9,12,13]

l=[x**2 for (x,y)in zip(xl,yl)if y>10]

2.懒惰求值

介绍迭代器时提到过,迭代器的元素是实时计算出来的。在使用该元素之前,元素并不会占据内存空间。与之相对应,列表在建立时,就已经产生了各个元素的值,并保存在内存中。迭代器的工作方式正是函数式编程中的懒惰求值。我们可以对迭代器进行各种各样的操作,但只有在需要时,迭代器才会计算出具体的值。如,,列表提前准备数据的方式,就浪费了很多运算资源。

3.itertools包

这个包提供了更加灵活的生成迭代器的工具,这些工具的输入大都是已有的迭代器。P193

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容

  • ​ 二零一九年十一月二十二日,多云,凉。 入了冬的天气日渐消瘦,前一刻还有明媚的阳光,下一秒便有飞雪不请...
    星梦若晴阅读 93评论 0 4
  • 黄花已坠 衰败犹如剧本 灾难的帷幕里 一簇火苗 奄奄一息 僧舍里推卸着重任 排成长队的灵魂 衣衫褴褛,脚掌浸透 巨...
    林木人阅读 207评论 0 2
  • 又到一年端午季。 记得很小的时候,曾跟外婆一起包过粽子。把粽叶卷起来,塞入泡好的糯米,用筷子插紧,再用线绳包裹起来...
    恩佑阅读 1,212评论 12 13