首页 > 编程语言 >05. 函数式编程

05. 函数式编程

时间:2023-12-24 19:36:57浏览次数:46  
标签:__ return 函数 05 self 编程 def


目录

1、前言

2、什么是函数式编程

2.1、函数是一等公民

2.2、避免状态和可变数据

3、函数式编程的核心概念

3.1、高阶函数

3.2、Lambda(匿名函数)

3.3、递归 & 尾递归优化

3.4、functools模块

3.4.1、partial

3.4.2、reduce

3.4.3、lru_cache

3.4.4、wraps

4、函数式编程的实际应用

4.1、函数式编程风格的代码

4.2、不可变性和线程安全性

5、小结


1、前言

在《04.函数》一文中介绍了Python中的函数,以及函数的基础使用。函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。而函数式编程(Functional Programming),是一种抽象程度很高的编程规范。

2、什么是函数式编程

函数式编程是一种编程范式,它将计算视为数学函数的评估,并避免改变状态和可变数据。它是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。

函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!在函数式编程中,函数是一等公民,允许其作为参数传递、赋值给变量,以及作为函数的返回值。

2.1、函数是一等公民

在Python中,函数是一等公民,这意味着函数可以被赋值给变量,作为参数传递给其他函数,以及作为函数的返回值。

def square(x):
    return x ** 2

# 函数赋值给变量
f = square

# 函数作为参数传递
def apply_func(func, x):
    return func(x)

result = apply_func(f, 5)  # 结果为25

2.2、避免状态和可变数据

函数式编程鼓励使用不可变数据和避免副作用。这有助于减少程序的复杂性和提高代码的可维护性。

# 不可变数据
immutable_list = (1, 2, 3)

# 避免副作用
def add_to_list(element, lst):
    return lst + [element]

original_list = [1, 2, 3]
new_list = add_to_list(4, original_list)  # new_list为[1, 2, 3, 4]

3、函数式编程的核心概念

从上面的例子可以看出,编写高阶函数,就是让函数的参数能够接收别的函数。把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。

3.1、高阶函数

高阶函数是函数式编程的基石,它们可以接受一个或多个函数作为参数,并/或返回一个新的函数。Python中内置了很多高阶函数,如map/reduce、filter、sorted等。

  • map函数是一个高阶函数,将函数应用于可迭代对象的每个元素。
if __name__ == '__main__':
    numbers = [1, 2, 3, 4]
    squared = map(lambda x: x ** 2, numbers)  # 结果为[1, 4, 9, 16]
    print(list(squared))
  • reduce函数用于累积可迭代对象的元素,把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算。
from functools import reduce

if __name__ == '__main__':
    numbers = [1, 2, 3, 4]
    total = reduce(lambda x, y: x + y, numbers)  # 结果为1+2+3+4=10
    print(total)
  • filter函数用于过滤可迭代对象的元素。
if __name__ == '__main__':
    numbers = [1, 2, 3, 4, 5, 6]
    even_numbers = filter(lambda x: x % 2 == 0, numbers)  # 结果为[2, 4, 6]
    print(list(even_numbers))

3.2、Lambda(匿名函数)

Lambda函数是一种简洁的函数定义方式,通常用于临时需要一个简单函数的情况。当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。在Python中,对匿名函数提供了有限支持。就像前面filter函数中的lambda x: x % 2 == 0,该匿名函数实际上是:

def func(x):
    return x % 2 == 0

其中关键字lambda表示匿名函数,冒号前面的x表示函数参数。匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数。如:

if __name__ == '__main__':
    # 使用lambda定义匿名函数
    multiply = lambda x, y: x * y
    result = multiply(3, 4)  # 结果为12
    print(result)

3.3、递归 & 尾递归优化

函数式编程中,递归是一种强大的技术,可以通过函数调用自身来解决问题。

# 阶乘的递归实现
def factorial(n):
    if n == 0 or n == 1:
        return 1
    else:
        return n * factorial(n - 1)

在Python并不是尾递归优化的语言,但你可以使用一些技巧来模拟尾递归优化,如使用尾递归优化装饰器。

class TailRecursive:
    def __init__(self, func):
        self.func = func
        self.args = None
        self.kwargs = None

    def __call__(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs
        while self.args is not None:
            result = self.func(*self.args, **self.kwargs)
            if callable(result):
                result()
            else:
                self.args = None
                self.kwargs = None
        return result

# 使用尾递归优化装饰器
@TailRecursive
def factorial_tail_recursive(n, acc=1):
    if n == 0:
        return acc
    else:
        return factorial_tail_recursive(n - 1, n * acc)

result = factorial_tail_recursive(5)  # 结果为120

3.4、functools模块

functools 是 Python 标准库中的一个模块,提供了一些与函数相关的高阶功能。它包含了一些用于函数操作的工具,其中一些特别有用于函数式编程。上面介绍reduce方法时,就已经有引入了该模块了。下面详细介绍几个常用方法,更多具体的可以详细查看API。

3.4.1、partial

该函数用于部分应用(partial application)一个函数,即固定函数的一些参数,返回一个新的函数。

from functools import partial

def power(base, exponent):
    return base ** exponent

square = partial(power, exponent=2)
result = square(4)  # 结果为16

3.4.2、reduce

该函数通常用于对可迭代对象的所有元素进行累积操作。

from functools import reduce

numbers = [1, 2, 3, 4]
product = reduce(lambda x, y: x * y, numbers)  # 结果为24

3.4.3、lru_cache

该函数用于实现缓存机制,可以缓存函数的结果,以避免重复计算。

from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

3.4.4、wraps

该函数用于在装饰器中正确处理被装饰函数的元信息,如文档字符串和函数名。

from functools import wraps

def my_decorator(f):
    @wraps(f)
    def wrapper(*args, **kwds):
        print('Calling decorated function')
        return f(*args, **kwds)
    return wrapper

@my_decorator
def example():
    """Docstring"""
    print('Called example function')

这些功能使得 functools 成为编写更加灵活和可维护的代码的有用工具。在函数式编程、装饰器和缓存等方面,functools 提供了一些实用的功能。

4、函数式编程的实际应用

4.1、函数式编程风格的代码

函数式编程风格的代码通常更简洁、清晰,具有更好的可读性。

# 命令式编程
result = []
for number in numbers:
    result.append(number * 2)

# 函数式编程
result = map(lambda x: x * 2, numbers)

4.2、不可变性和线程安全性

函数式编程中的不可变性使得代码更容易在多线程环境中工作,因为不需要担心共享状态的问题。

# 命令式编程
shared_state = 0

def increment_state():
    global shared_state
    shared_state += 1

# 函数式编程
immutable_state = 0

def increment_state(state):
    return state + 1

5、小结

本文Python中函数式编程的基础概念、语法和实际应用。通过深入理解和应用函数式编程,你可以写出更具表达力、模块化和可维护性的代码。在实际项目中,根据需要灵活选择编程范式,将函数式编程的思想融入到你的Python代码中,发挥Python强大而灵活的特性。

标签:__,return,函数,05,self,编程,def
From: https://blog.51cto.com/u_15423953/8956777

相关文章

  • Go编程基础教程:Go容器化技术
    作者:禅与计算机程序设计艺术1.背景介绍目前互联网服务开发已经从单体应用模式升级到微服务架构模式。在微服务架构模式下,服务之间会相互调用,为了更好地管理和调优这些分布式系统,需要对其进行容器化,使得各个服务可以独立部署、资源分配、隔离等方面更加灵活高效。本文将通过Go语言......
  • C语言全局变量的extern+typedef函数指针+uvm_queue/pool/config_db/resource_db/barri
    C语言全局变量的extern全局变量在不同的文件引用,需要加上extern,才能引用到。如果没有extern关键词,则认为是一个定义,而不是引用,引发同名冲突。函数也是一样。要在本文件引用其它文件的函数,需要增补extern关键字。而其它文件,声明和定义过该函数。typedef函数指针https://zhuan......
  • 字符函数和字符串函数:strcmp、strncpy——《初学C语言第37天》
    //////————strcmp(比较两个字符串(的内容,ASCII值))————>头文件#include<string.h>//第一个字符串大于第二个字符串,则返回大于0的数字//第一个字符串等于第二个字符串,则返回0//第一个字符串小于第二个字符串,则返回小于0的数字//那么如何判断两个字符串?//比较方法:下标逐步......
  • C++ 内联函数
    @TOC前言内联函数(InlineFunctions)是C++中一个重要的编程概念,它允许开发者在代码中使用一种特殊的方式来声明和定义函数,以提高程序的性能和可维护性。本文将详细讨论C++中的内联函数,包括如何定义、为何使用、以及其潜在优缺点。1.内联函数的基本概念内联函数是一种特殊的C++函数,通......
  • mysql8.0 OCP 105
    105、Choosefour.YoumuststoreconnectionparametersforconnectingaLinux-basedMySQLclienttoaremoteWindows-basedMySQLserverlisteningonport3309.您必须存储连接参数,以便将基于linux的MySQL客户端连接到侦听端口3309的基于Windows的远程MySQL服务器。Wh......
  • SQL的right()函数
    RIGHT()是SQL中的一个字符串函数,用于从字符串的右侧返回指定数量的字符。使用场景:提取字符串右侧的字符:当你有一个字符串,并希望从中提取出右侧的某些字符时,可以使用RIGHT()函数。固定长度的字符串处理:当你处理固定长度的字符串,并需要提取其中的一部分时,可以使用RIGHT()......
  • Typescript 函数详解
    前言虽然JS/TS支持面向对象编程,但大部分时候还是在写函数。函数是一等公民。本文介绍下如何在TypeScript中使用函数,包括:函数类型声明函数参数类型:可选参数、默认参数、剩余参数函数返回值类型this类型函数重载函数类型面试中经常会被问到,JS中有哪几种数据类型。其中就会有函......
  • Go 语言学习指南:变量、循环、函数、数据类型、Web 框架等全面解析
    学习基础知识掌握Go语言的常见概念,如变量、循环、条件语句、函数、数据类型等等。深入了解Go基础知识的好起点是查阅Go官方文档文章链接:Go编程语言详解:用途、特性、与Python和C++的比较基本语法了解Go语言的基本语法,包括Go程序的执行方式、包引入、主函数等Go......
  • Go 语言学习指南:变量、循环、函数、数据类型、Web 框架等全面解析
    学习基础知识掌握Go语言的常见概念,如变量、循环、条件语句、函数、数据类型等等。深入了解Go基础知识的好起点是查阅Go官方文档文章链接:Go编程语言详解:用途、特性、与Python和C++的比较基本语法了解Go语言的基本语法,包括Go程序的执行方式、包引入、主函数等Go......
  • 2023-2024-1 20231405《计算机基础与程序设计》第十三周学习总结
    2023-2024-120231405《计算机基础与程序设计》第十三周学习总结作业信息作业属于哪个课程https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP作业要求在哪里https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP/homework/13009作业的目标自学......