[原创]Python入门学习之函数式编程

一 前言

  初次接触函数式编程是在学习分布式计算的时候,那时候对map/reduce是不明觉厉,也没有懂多少原理方面的东西。Python中的函数式编程也算是初步了解一下map/reduce。所谓函数式编程,本质上是可以归结为面向过程的程序设计,但是它的思想很接近数学计算。它比一般的编程范式要更抽象,而且纯粹的函数式编程语言编写的函数是没有变量的,只要确定了输入,那也就确定了输出。它的另外一个特点就是把函数本身作为参数传入到另一个函数中,允许返回一个函数。

二 高阶函数(High-order Function)

  在Python中,函数名本质上也是一个变量。我们可以将一个函数名赋值给一个变量,再通过这个变量来调用函数。在使用python面向过程的程序设计中,一个带有变量的函数是很普遍的设计,但是如果这个变量是一个函数,那么这个带有变量的函数我们就称之为高阶函数了。

  一个简单的高阶函数示例:

def fun(n):
    return n+1

def highorder(x, y, f):
    return f(x)+f(y)

上面定义的highorder就是一个高阶函数,它是可以在参数中接收其他函数的函数。

三 Map/Reduce

  有了上面的高阶函数基础,现在再来理解Map/Reduce就很容易了。Map函数接收两个参数,一个是函数,另一个是Iterable。Map将函数依次作用在Iterable的每一个元素上,并把结果作为新的Iterator返回。

  看下面的示例:

def fun(n):
    return n*2

m=map(fun, [1,2,3,4,5])
print(m)

E:\Study\python>python hello_python.py
[2, 4, 6, 8, 10]

  map把函数fun依次作用在列表的每一个元素上,就得到了[2,4,6,8,10]。

  如果嫌定义一个fun函数比较麻烦,可以使用lambda来进行简化,如下:

m=map(lambda n:n*2, [1,2,3,4,5])

  再看Reduce的用法。Reduce同Map一样,也是将一个函数依次作用在一个序列上,但是要求这个函数必须接收两个函数。Reduce再把函数作用在前两个参数的结果与下一个序列的元素上。

  下面就用Reduce来实现一个序列求和运算,见下例:

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

r=reduce(add, [1,2,3,4,5])
print(r)

E:\Study\python>python hello_python.py
15

  它的lambda版本为:

r=reduce(lambda x,y:x+y, [1,2,3,4,5])

四 返回函数

  在前面就已经表述过函数是可以被赋值给一个变量的,那么既然函数可以返回一个变量,当然也是可以返回一个函数的。别看返回变量和返回函数本质上区别不大,但是这种返回函数的机制却在应用中有着极大的作用。

  来看下面的示例:

def wrapper(*param):
    def calc():
        sum=0
        for x in param:
            sum=sum+x
        return sum
    return calc;

f=wrapper(1,2,3,4,5)

print(f())

E:\Study\python>python hello_python.py
15

  定义一个包裹函数wrapper,接收不定数量个参数。在调用此函数后,其会返回一个内部定义的函数,这个函数要在真正调用它时才会执行。另外还要注意的是,calc函数中访问的数据是由wrapper带进来的,并且这些参数会与calc被保存在一起,我们称之为“闭包”(closure)。

五 闭包(Closure)

  初次接触闭包,对其并不是十分的理解。仍以四中的代码作为示例。

  wrapper是一个函数,包括不定个数的参数param。比较特殊的地方是这个函数体中还定义了一个新的函数calc,这个新函数的函数体内正引用了一个外部函数wrapper的参数,也就是说,外部函数传递过来的参数已经和calc函数绑定到了一起,形成了一个新函数。我们可以把param看成是这个新函数的一个配置信息。配置信息如果不一样,那函数的输出当然也就不一样了。

  为了更好的理解闭包,看以下代码示例:

def wrapper(conf):
    def calc(n):
        return conf+n
    return calc

f1=wrapper(1)
f2=wrapper(2)

print(f1(100))
print(f2(100))

E:\Study\python>python hello_python.py
101
102

  分析上述代码,调用wrapper(1)时会返回一个函数,并且这个函数的配置信息是conf的值为1。再调用wrapper(2)时会返回另外一个函数,并且这个函数的配置信息是conf的值为2。所以在随后的我们都传入100参数来调用f1和f2时得到的结果为101和102,其根本原因就在于两个函数的配置信息不一样。

  值得我们注意的是,并不是外部函数的所有信息都会被内部函数做为配置信息,只有外部函数的参数才会被内部函数作为配置信息。至于外部函数的局部变量,就不会被做为配置信息了。

    

六 装饰器(Decorator)

  发明Decorator的初衷是为了解决在不修改原有函数代码的情况下,在函数调用前后增加其他功能,比如打印日志等。Decorator本质上就是一个返回函数的高阶函数,看下面这个打印日志的decorator,代码如下:

def decorator(func):
    def wrapper():
        print("Before invoked:")
        func()
        print("After invoked:")
    return wrapper        

def func():
    print("Func invoked:")

f=decorator(func)
f()

E:\Study\python>python hello_python.py
Before invoked:
Func invoked:
After invoked:

  上述代码给func定义了一个装饰器,在调用这个装饰器时返回一个函数,在这个函数中加上需要的代码后再调用func。但这里有一个问题,那就是原来可以直接调用func,现如今却要调用f了。要解决这个问题很容易,因为在python中函数是可以赋值给一个变量的,只需要将f改成func就可以了。如下所示:

func=decorator(func)
func()

  python中为实现这个机制提供了一个语法:@。在func前加上@decorator即可,相当于执行了func=decorator(func),这样就解决了使用相同的名字来调用增加功能后的代码。如下所示:

def decorator(func):
    def wrapper():
        print("Before invoked:")
        func()
        print("After invoked:")
    return wrapper        

@decorator
def func():
    print("Func invoked:")

func()

  另外还有如何给decorator增加参数以及如何修改wrapper的__name__属性为func的内容,这里就不讲述了。

七 偏函数(Partial Function)

  何谓偏函数?偏函数就是给函数增加默认参数后的函数。在python中,可以使用functools.partial来生成一个函数的偏函数。拿python中的int()做示例,int()函数默认是按十进制转换,如果想生成一个按8进制转换的偏函数,可以如下实现:

print(int(‘12345‘))

int8=functools.partial(int, base=8)
print(int8(‘12345‘))

八 总结

  在这篇文章中,主要讲述了函数式编程中的几个基本概念。个人感觉最难理解的就是Decorator了,特别是其中的所谓配置信息。如有错误之处,敬请留言!!!

时间: 2024-08-17 00:37:21

[原创]Python入门学习之函数式编程的相关文章

[原创]Python入门学习之数据结构

Preamble: 在未学习python之前,使用c/c++已有5年之久.虽对python刚学习,但也领略到了python的强大之处,开拓了自己的视野和思维. 一 变量 python中的变量与c/c++中的变量不同.在c/c++中,变量的本质就是内存的地址,但在python中,当我们定义一个变量并赋值时,如下: a='ABC' python的解释器干了两件事情:(1)在内存中创建一个‘ABC’的字符串:(2)在内存中再创建一个名为a的变量,并把它指向‘ABC’.也就是说,对于python占用的内

[原创]Python入门学习之高级特性

一 前言 学习高级特性的时候也许会感觉到有些许的难,这些新的特性在以前c/c++中是没有遇到过的,而且c/c++也不支持这样简便但又强大的语法. 二 切片 谈到切片,可以想像到切萝卜,拿到萝卜的某一段,用这个来比喻这里的切片非常贴切.python中的切片操作就是取list或者tuple中的某一段. 比如,有以下定义的list: #define a list l=['Luffy','Corey','Nancy','Jeffrey','Kyle','Avery','Jason','Sunny'] 取

python入门学习:8.类

python入门学习:8.类 关键点:类 8.1 创建和使用类8.2 使用类和实例8.3 继承8.4 导入类 8.1 创建和使用类 ??面向对象编程是最有效的软件编写方法之一.在面向对象编程中,你编写表示现实世界中的事物和情景的类,并基于这些类来创建对象.根据类来创建对象被称为实例化,这让你能够使用类.8.1.1 创建dog类??下面创建一个dog类: 1calss Dog(): 2 3    def __init__(self,name,age): 4        self.name = n

Python入门学习指南--内附学习框架

Python入门学习指南 最近开始整理python的资料,博主建立了一个qq群,希望给大家提供一个交流的同平台: 78486745 ,欢迎大家加入共同交流学习. 对于初学者,入门至关重要,这关系到初学者是从入门到精通还是从入门到放弃.以下是结合Python的学习经验,整理出的一条学习路径,主要有四个阶段 NO.1 新手入门阶段,学习基础知识 总体来讲,找一本靠谱的书,由浅入深,边看边练. 网上的学习教程有很多,多到不知道如何选择.所有教程在基础知识介绍方面都差不多,区别在于讲的是否足够细(例如运

PYTHON修饰器的函数式编程

转自:http://coolshell.cn/articles/11265.html Python修饰器的函数式编程 Python的修饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西.虽然好像,他们要干的事都很相似--都是想要对一个已有的模块做一些"修饰工作",所谓修饰工作就是想给现有的模块加上一些小装饰(一些小功能,这些小功能可能好多模块都会用到),但又不让这个小装饰(小功能

python 入门学习 载抄

python入门 解释型语言 和编译型语言 计算机本身不能识别高级语言,当我们运行一个程序的时候,需要一个“翻译” 来把 高级语言转换成计算机能读懂的语言. “翻译”过程分两种: 编译 编译型语言在执行程序前,首先会通过编译器执行一个编译的过程,把程序编译成机器语言. 之后,程序再次运行的时候,就不要“翻译”了,而是可以直接执行.比如C语言. 编译型语言的优点在于在运行程序的时候不用解释,可直接利用已经翻译过的文件. 解释 解释型语言就没有编译的过程,而是在程序运行的时候,通过解释器逐行解释代码

Python入门学习:1.变量和简单的数据类型

python入门学习:1.变量和简单的数据类型 关键点:变量.字符串.数字 1.1 变量的命名和使用1.2 字符串1.3 数字1.4 注释 1.1 变量的命名和使用 ??变量,顾名思义是一个可变的量,每个变量都存储一个值--与变量关联的信息. 1message = "hello world!"2# message 是一个变量3print(message) ??在python中使用变量时,需要遵循一些规则和指南. 变量名只能包含字母.数字和下划线.变量名可以字母或者下划线打头,但不能以数

python入门学习:7.函数

python入门学习:7.函数 关键点:函数 7.1 定义函数7.2 传递实参7.3 返回值7.4 传递列表7.5 传递任意数量的实参7.6 将函数存储在模块中 7.1 定义函数 ??使用关键字def告诉python要定义一个函数,紧接着跟着函数名,冒号.后面的缩进构成函数体.例如: 1def func_name():2    函数体34def greet_user():5    """显示简单问候语"""6    print("hel

Python入门学习:一步步教你怎么用Python写贪吃蛇游戏

前几天,有人提到贪吃蛇,一下子就勾起了我的兴趣,毕竟在那个Nokia称霸的年代,这款游戏可是经典中的经典啊!而用Python(蛇)玩Snake(贪吃蛇),再合适不过了. 这里通过一个Python入门学习的例子跟大家详细讲解一下! 先通过下面这个效果图来感受下吧! 1 环境 操作系统:Windows Python版本:3.7.3 2 需求分析 我们先来回顾下贪吃蛇中的游戏元素及游戏规则. 首先呢,需要有贪吃蛇.有食物:需要能控制贪吃蛇来上下移动获取食物:贪吃蛇在吃取食物后,自身长度增加,同时食物消