Python函数式编程之面向过程面向对象及函数式简析

目录
  • Python 函数式编程
  • 同一案例的不同写法,展示函数式编程
    • 面向过程的写法
    • 面向对象的写法
    • 接下来进入正题,函数式编程的落地实现
  • Python 函数式编程的特点
  • 纯函数

Python 函数式编程

Python 不是纯粹的函数式语言,但你可以使用 Python 进行函数式编程

典型的听君一席话,如听一席话,说白了就是 Python 具备函数式编程的特性,

so,可以借用函数式语言的设计模式和编程技术,把代码写成函数式编程的样子

一般此时我会吹嘘一下,函数式代码比较简洁和优雅~

好了,已经吹嘘完了。

以上内容都属于讲道理的范围,那在 Python 中有哪些适合函数式编程的技能点

又有哪些不适的点呢?

下述 2 点先有个印象就行

优点:生成器表达式,这个后面咱会反复提及,具备很多高阶函数,例如 reducemapfilter 三巨头。

缺点:没有无限递归等~

如果你去百度 “什么是函数式编程”,很多地方会给出答案

函数式编程:允许把函数本身作为参数传入另一个函数,还允许返回一个函数。

有道理!

其实函数式编程就是在函数中定义表达式和实现表达式的求职,说白了就是用函数落地你的代码。

看起来好像是废话,它还有一个补充的说明,在函数式编程中要避免状态变化和使用可变对象。

其中避免状态变化 重点要关注赋值语句以及它如何改变状态,因此你在函数式编程中,不会看到 globalnolocal 等内容。

同一案例的不同写法,展示函数式编程

概念与原理都是比较抽象的,咱还是少说概念,这个留到未来你自己总结就好,直接展示源码差异。

计算 1~100 内,计算 5 与 7 的倍数之和

面向过程的写法

count = 0
for num in range(1, 101):
    if num % 5 == 0 or num % 7 == 0:
        count += num
print(count)

在面向过程的写法中,逻辑都是从上向下进行运行的,例如 num 从 1 数到 100,如果对 5 或者对 7 取余等于 0,那表示可以整除,然后将 count 与对应的 num 相加,得到最后的余数。

这种思路是纯面向过程的写法,一般我们学习编程时,首先学会的就是该类写法。

面向对象的写法

该类写法有两种,一种是使用 Python 内置的列表实现,一种是自己声明一个类来实现。

第一种写法:

count = list()
for num in range(1, 101):
    if num % 5 == 0 or num % 7 == 0:
        count.append(num)
print(sum(count))

在上述写法中,变量 count 声明一个 list,即列表对象,但是整理看起来还是有些过程式编程语言的影子。

例如最后的 sum(count) 的使用就有些奇怪,看不出来面向对象的影子。

接下来,咱们创建一个自定义的类,进行逻辑实现。

class My_List_Sum(list):
    def sum(self):
        count = 0
        for n in self:
            count += n
        return count
count = My_List_Sum()
for num in range(1, 101):
    if num % 5 == 0 or num % 7 == 0:
        count.append(num)
print(count.sum())

上述代码,我们自行实现了一个 My_List_Sum 类,让它继承自 list,此时你应该明白,list 就是一个类名,然后在类的内部实现了 sum 方法,再调用该对象的 sum 方法,完美的应用了面向对象的写法。

接下来进入正题,函数式编程的落地实现

在正式编写前,需要回忆一些基础知识,例如 lambda 表达式以及列表相加。

判断一个数字是 5 或者 7 的倍数, lambda 写法如下:

multiple = lambda x: x % 5 == 0 or x % 7 == 0
a = multiple(3) # False
b = multiple(5) # True
c = multiple(7) # False
print(a, b, c)

列表相加代码如下:

print([1]+[2]) # [1,2]

有了上述内容,可以编写一个递归函数,实现对应的逻辑,代码的说明已经添加到注释中。

def tool(n: int, end: int, filter_func) -> list:
    """返回一个筛选之后的列表
    :param n: 起始值
    :param end: 终止值
    :param filter_func: 判断表达式
    """
    # 如果到达上限,直接返回空列表
    if n == end: return []
    # 如果满足过滤条件,返回该值与下一个值组成的列表
    if filter_func(n):
        return [n] + tool(n + 1, end, filter_func)
    else:
        # 不满足过滤条件,直接返回下一个值
        return tool(n + 1, end, filter_func)
# 测试代码
ret = tool(1, 101, lambda x: x % 5 == 0 or x % 7 == 0)
print(ret)
print(sum(ret))

上述代码即为求和的函数式实现,其中部分逻辑如下:

  • 给定初始值与上限值,当迭代的值等于上限值时,返回空列表,即运行结束;
  • 传入一个判断条件,本案例中为一个 lambda 表达式,用于判断 5 和 7 的倍数;
  • 当满足条件时,进行的是相加+迭代工作,当不满足条件时,直接进入下一次迭代。

当然还有一种函数式编程的写法,代码如下:

print(sum(n for n in range(1, 101) if n % 5 == 0 or n % 7 == 0))

这里用到的生成器后文会进行说明。

Python 函数式编程的特点

在 Python 中,函数即对象,例如声明一个函数之后,你可以调用其属性。

下述代码展示的即为函数对象的属性,其余内容可以自行再做测试。

def my_func(var1, var2, **kw):
    return var1 + var2
print(type(my_func))  # <class 'function'>
print(my_func.__code__)
print(my_func.__dict__)
print(my_func.__code__.co_code)
print(my_func.__code__.co_filename)
print(my_func.__code__.co_argcount)

函数式编程之所以高效,其中一个很重要的原因就是延迟计算,也叫做惰性求值,这些在后面都将逐步展开,现在依旧是接收一下印象概念。

正是因为函数即对象,所有才有本文开篇那段对函数式编程的定义。

函数可以使用其它函数作为参数,或者返回另一个函数,所以在实际编码过程中,我们将会把函数转换成其它代码中的 “对象”,从而实现函数式编程。

接下来咱们要接触一下 Python 中的纯函数概念以及应用。

纯函数

纯函数是一个概念,也就是让函数不会对函数外作用域产生影响,即作用域为本地。

说简单点,就是在函数内部避免赋值操作,当然类似 global 等关键字也避免使用。

针对此,lambda 表达式就是纯函数。

首先查看一个纯函数的例子:

def my_func(num: int) -> int:
    return num * 100

上述代码中函数的返回值仅与 num 有关,满足下面两个条件:

  • 没有改变全局变量;
  • 没有更新可变数据结构,例如列表,字典。

接触完毕纯函数概念之后,下面了解一下函数作为对象的落地应用。

在 Python 中声明一个类,默认会携带部分内置的方法,例如:

from typing import Callable
# 声明一个类,该类无意义,仅测试使用
class Ext:
    # 传入的函数,可携带1~2个参数
    def __init__(self, test_demo: Callable[[int], int]) -> None:
        self.func = test_demo
    # 返回结果扩大2倍
    def __call__(self, arg: int) -> int:
        return self.func(arg) * 2
def one_func(var):
    return var + 1
def two_func(var):
    return var * 3
def three_func(var):
    return var
a = Ext(one_func)
print(a(3))  # 8
b = Ext(two_func)
print(b(3))  # 18
c = Ext(three_func)
print(c(3))  # 6

上述代码使用了一个新的模块 typing,该模块是 Python 3.5 之后新增的模块,主要为 Python 提供静态类型的检查 。

本案例中导入的是回调函数 Callable,格式如下:

Callable[[Arg1Type, Arg2Type],ReturnType]

其中内部中括号 Arg1Type 是参数类型,ReturnType 为返回值类型。

上述三个函数的签名都与 Callable 定义的一致,所以都可以作为 test_demo 参数的值去传递。

以上就是Python函数式编程之面向过程面向对象及函数式简析的详细内容,更多关于Python函数式编程面向过程面向对象及函数式的资料请关注我们其它相关文章!

(0)

相关推荐

  • 浅谈Python 函数式编程

    匿名函数lambda表达式 什么是匿名函数? 匿名函数,顾名思义就是没有名字的函数,在程序中不用使用 def 进行定义,可以直接使用 lambda 关键字编写简单的代码逻辑.lambda 本质上是一个函数对象,可以将其赋值给另一个变量,再由该变量来调用函数,也可以直接使用. #平时,我们是先定义函数,再进行调用 def power(x): return x ** 2 print(power(2)) #使用lambda表达式的时候,我们可以这样操作 power = lambda x : x **

  • 浅析Python函数式编程

    Functional Programming,函数式编程.Python对函数式编程提供部分支持.对于纯函数编程,对任一函数,只要输入是确定的,输出就是确定的,可称之为无副作用. 一.高阶函数 1.变量指向函数 我们知道函数的计算结果可以赋值给变量,例如x = abs(-5). 同理,变量也可以指向函数,例如f = abs. 如果一个变量指向了一个函数,那我们直接调用abs(x)与执行f(x)返回的结果是完全相同. 2.函数名也是变量 我们也可以把函数名看成是一个变量,例如abs()函数.执行语句

  • Python函数式编程指南(一):函数式编程概述

    1. 函数式编程概述 1.1. 什么是函数式编程? 函数式编程使用一系列的函数解决问题.函数仅接受输入并产生输出,不包含任何能影响产生输出的内部状态.任何情况下,使用相同的参数调用函数始终能产生同样的结果. 在一个函数式的程序中,输入的数据"流过"一系列的函数,每一个函数根据它的输入产生输出.函数式风格避免编写有"边界效应"(side effects)的函数:修改内部状态,或者是其他无法反应在输出上的变化.完全没有边界效应的函数被称为"纯函数式的"

  • Python函数式编程之面向过程面向对象及函数式简析

    目录 Python 函数式编程 同一案例的不同写法,展示函数式编程 面向过程的写法 面向对象的写法 接下来进入正题,函数式编程的落地实现 Python 函数式编程的特点 纯函数 Python 函数式编程 Python 不是纯粹的函数式语言,但你可以使用 Python 进行函数式编程 典型的听君一席话,如听一席话,说白了就是 Python 具备函数式编程的特性, so,可以借用函数式语言的设计模式和编程技术,把代码写成函数式编程的样子 一般此时我会吹嘘一下,函数式代码比较简洁和优雅~ 好了,已经吹

  • python实现飞机大战(面向过程)

    本文实例为大家分享了python实现飞机大战的具体代码,供大家参考,具体内容如下 游戏的实现本质是多个图片的快速切换,类似动画一样,达到动态的效果.比如子弹的发射,实际上是一个子弹的照片根据列表中存储的位置多次粘贴到界面上.还有飞机的移动是首先收集到移动信息将坐标变化,然后下一次覆盖页面的时候进行粘贴. import pygame import time from pygame.locals import * hero_x = 150 hero_y = 600 # 子弹夹 mybullet =

  • JavaScript实现选项卡功能(面向过程与面向对象)

    目录 面向过程 面向对象 面向过程 注意: ul>li 标签属性中 的index属性值是串联起ol>li与ul>li的关键,通过调用相同索引下标的数组中的不同属性的属性值达到切换内容的效果. 通过事件委托找到对应的ul>li 进行css属性的删除与新增做到背景颜色改变和内容改变的效果. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&qu

  • 《JavaScript函数式编程》读后感

    本文章记录本人在学习 函数式 中理解到的一些东西,加深记忆和并且整理记录下来,方便之后的复习. 在近期看到了<JavaScript函数式编程>这本书预售的时候就定了下来.主要目的是个人目前还是不理解什么是函数式编程.在自己学习的过程中一直听到身边的人说面向过程编程和面向对象编程,而函数式就非常少.为了自己不要落后于其他同学的脚步,故想以写笔记的方式去分享和记录自己阅读中所汲取的知识. js 和函数式编程 书中用了一句简单的话来回答了什么是函数式编程: 函数式编程通过使用函数来将值转换为抽象单元

  • JavaScript与函数式编程解释

    作者:月影 牢记:函数式编程不是用函数来编程!!!23.4函数式编程  23.4.1 什么是函数式编程 什么是函数式编程?如果你这么直白地询问,会发现它竟是一个不太容易解释的概念.许多在程序设计领域有着多年经验的老手,也无法很明白地说清楚函数式编程到底在研究些什么.函数式编程对于熟悉过程式程序设计的程序员来说的确是一个陌生的领域,闭包(closure),延续(continuation),和柯里化(currying)这些概念看起来是这么的陌生,同我们熟悉的if.else.while没有任何的相似之

  • 用函数式编程技术编写优美的 JavaScript

    级别: 初级 Shantanu Bhattacharya (shantanu@justawordaway.com), 首席顾问, Siemens Information Systems Limited 2006 年 7 月 20 日 函数式或声明性编程是非常强大的编程方法,正逐渐在软件行业流行起来.这篇文章将介绍一些相关的函数式编程概念,并提供有效使用这些概念的示例.作者将解释如何使用 JavaScript(TM)(JavaScript 能导入函数式编程的构造和特性)编写优美的代码. 简介 函数

  • 深入了解java 8的函数式编程

    前言 关于"Java 8为Java带来了函数式编程"已经有了很多讨论,但这句话的真正意义是什么? 本文将讨论函数式,它对一种语言或编程方式意味着什么.在回答"Java 8的函数式编程怎么样"之前,我们先看看Java的演变,特别是它的类型系统,我们将看到Java 8的新特性,特别是Lambda表达式如何改变Java的风景,并提供函数式编程风格的主要优势. 函数式编程语言是什么? 函数式编程语言的核心是它以处理数据的方式处理代码.这意味着函数应该是第一等级(First-

  • Java8新特性:函数式编程

    首先需要清楚一个概念:函数式接口:它指的是有且只有一个未实现的方法的接口,一般通过FunctionalInterface这个注解来表明某个接口是一个函数式接口.函数式接口是Java支持函数式编程的基础. 1 Java8函数式编程语法入门 Java8中函数式编程语法能够精简代码. 使用Consumer作为示例,它是一个函数式接口,包含一个抽象方法accept,这个方法只有输入而无输出. 现在我们要定义一个Consumer对象,传统的方式是这样定义的: Consumer c = new Consum

  • javascript函数式编程基础

    目录 一.引言 二.什么是函数式编程 三.纯函数(函数式编程的基石,无副作用的函数) 四.函数柯里化 五.函数组合 六.声明式和命令式代码 七.Point Free 八.示例应用 九.总结 一.引言 函数式编程的历史已经很悠久了,但是最近几年却频繁的出现在大众的视野,很多不支持函数式编程的语言也在积极加入闭包,匿名函数等非常典型的函数式编程特性.大量的前端框架也标榜自己使用了函数式编程的特性,好像一旦跟函数式编程沾边,就很高大上一样,而且还有一些专门针对函数式编程的框架和库,比如:RxJS.cy

随机推荐