python基础之函数式编程

一、定义:

  

  函数作为参数作用:将核心逻辑传入方法体,使该方法的适用性更广,体现了面向对象的开闭原则;

  函数作为返回值作用:逻辑连续,当内部函数被调用时脱离当前逻辑。

二、高阶函数:

  1、定义:将函数作为参数或返回值的函数。

  2、常见内置高阶函数:

    

三、lambda表达式:

  

四、闭包:

  

五、函数装饰器(decorators):

  

六、基础代码:

  代码1:

  

"""
    函数式编程 -- 方法作为参数
"""

def fun01():
    print("fun01执行喽")

# 调用fun01,将返回值赋值给变量a
# a = fun01()

# 将函数值赋值给变量a(没有执行fun01)
a = fun01
# 调用变量a,间接执行函数fun01
a()

# 将方法fun01作为方法的参数func进行传递
def fun02(func):
    print("fun02执行喽")
    # 对于fun02的定义者而言,不知道也不需要知道func的具体逻辑.
    func()

fun02(fun01)



list01 = [1,2,33,4,45,6]
# def find_demo01(target):
#     for item in target:
#         if item> 5:
#             yield item
#
# def find_demo02(target):
#     for item in target:
#         if item % 2 != 0:
#             yield item
#
# def find_demo03(target):
#     for item in target:
#         if item < 3:
#             yield item

# --------------------------------------------
# 相同点:
def find_demo(target,func):
    for item in target:
        # 本行代码,又将不变的与变化的紧密相连
        # if condition01(item):
        # 本行代码,使用形参func将不变的与变化的隔离开.
        if func(item):
            yield item
# --------------------------------------------
# 提取不同点:
def condition01(item):
    return item> 5

def condition02(item):
    return item % 2 != 0

def condition03(item):
    return item < 3

for item in find_demo(list01,condition03):
    print(item)

  代码2:

  

"""
    lambda 表达式(匿名方法)
    语法: 
    lambda 参数:方法体
    练习:
    exercise05.py
"""


def fun01():
    print("我是普通方法")


fun01()



def fun02(a):
    print("我是普通方法,参数是,", a)


fun02(500)


def fun03():
    return True


print(fun03())

# -------------------------
a01 = lambda: print("我是lambda方法")
a01()

a02 = lambda a: print("我是lambda方法,参数是,", a)
a02(500)

a03 = lambda: True
print(a03())
#------------------------------------

from common.custom_list_tools import ListHelper
list01 = [1,2,33,4,45,6]

for item in ListHelper.find_all(list01,lambda item:item > 5):
    print(item)

for item in ListHelper.find_all(list01,lambda item:item % 2 != 0):
    print(item)

# 提取不同点:
# def condition01(item):
#     return item> 5
#
# def condition02(item):
#     return item % 2 != 0
#
# def condition03(item):
#     return item < 3

# for item in ListHelper.find_all(list01,condition01):
#     print(item)

  代码3:

  

"""
    高阶函数

"""
from day16.common.custom_list_tools import ListHelper


# 敌人类(编号/姓名/攻击力/血量/攻击速度...)
class Enemy:
    def __init__(self, id, name, hp, atk, atk_speed):
        self.id = id
        self.name = name
        self.hp = hp
        self.atk = atk
        self.atk_speed = atk_speed


list01 = [
    Enemy(101, "玄冥大老", 200, 800, 5),
    Enemy(102, "玄冥小老", 150, 700, 3),
    Enemy(103, "qtx", 800, 1000, 50),
    Enemy(104, "吕泽玛利亚", 0, 300, 2),
    Enemy(105, "赵金多", 500, 900, 10),
]

# 1. filter 过滤,类似于ListHelper.find_all.
# 过滤出编号大于102的敌人
# for item in filter(lambda e: e.id > 102, list01):
#     print(item.id)
#
# for item in ListHelper.find_all(list01, lambda e: e.id > 102):
#     print(item.id)

# 2. map 映射,类似于ListHelper.select
# 映射出所有敌人的姓名
for item in map(lambda e:e.name,list01):
    print(item)

for item in ListHelper.select(list01,lambda e:e.name):
    print(item)

# # 按照血量升序排列,类似于ListHelper.order_by
# for item in sorted(list01,key = lambda e:e.hp ):
#     print(item.hp)
#
# # 按照血量降叙排列
# for item in sorted(list01,key = lambda e:e.hp,reverse=True):
#     print(item.hp)

# ListHelper.order_by(list01,lambda e:e.hp)
# for item in list01:
#     print(item.hp)


# 获取攻击力最大的敌人
result = max(list01,key = lambda e:e.atk)
print(result.name)

result = ListHelper.get_max(list01,lambda e:e.atk)
print(result.name)

  代码4:

  

"""
    Encolsing 外部嵌套作用域
"""

# 全局变量G
g01 = 100

def fun01():
    # fun01局部变量L
    # E外部嵌套作用域
    a = 1

    def fun02():
        b = 2 # fun02局部变量L
        # print("fun02:", a) # 可以访问外部嵌套变量a
        # a = 2222 # 没有修改外部嵌套变量a,而是创建了新的局部变量a
        # print("fun02:",a)
        nonlocal a # 声明外部嵌套变量a
        a = 2222
        print("fun02:",a)

    fun02()
    print("fun01:",a)

fun01()

  代码5:

  

"""
    闭包

"""

def fun01():
    print("fun01执行喽")
    a = 1
    def fun02():
        print("fun02执行喽")
        print("外部变量是:",a)
    return fun02

# 得到的是内部函数
result = fun01()
# 调用内部函数,因为内部函数使用了外部变量,所以称之为闭包.
result()# 可以使用外部变量,说明外部函数在调用后没有释放.

# 案例:

def give_gift_money(money):
    """
        获取压岁钱
    """
    print("得到了%d压岁钱"%money)
    def child_buy(target,price):
        """
            孩子需要买东西
        """
        nonlocal money
        if money >= price:
            money -= price
            print("孩子花了%d钱,买了%s,还剩下%d钱."%(price,target,money))
        else:
            print("压岁钱不够了")
    return child_buy

action = give_gift_money(10000)
action("98k",3500)
action("小猪佩奇",300)
action("大黄蜂",8000)

# 体会:闭包使得逻辑连续(因为内部函数可以使用外部变量).

  代码6:

  

"""
    装饰器
     -- 闭包的应用
"""

# def say_hello():
#     print("hello")
#
#
# def say_goodbye():
#     print("goodbye")
#
#
# say_hello()
# say_goodbye()


# 需求:在两个方法实现的功能基础上,增加新功能(打印方法名称)

# def say_hello():
#     print(say_hello.__name__)
#     print("hello")
#
#
# def say_goodbye():
#     print(say_goodbye.__name__)
#     print("goodbye")
#
#
# say_hello()
# say_goodbye()

# 缺点:代码重复.
# 解决:提取打印方法名称的功能

# def print_func_name(func):
#     print(func.__name__)
#
# def say_hello():
#     # print(say_hello.__name__)
#     print_func_name(say_hello)
#     print("hello")
#
#
# def say_goodbye():
#     # print(say_goodbye.__name__)
#     print_func_name(say_goodbye)
#     print("goodbye")

# say_hello()
# say_goodbye()
# 缺点:在两个已有功能的内部,增加新功能,代码可读性差.

# def say_hello():
#     # print_func_name(say_hello)
#     print("hello")

# def say_goodbye():
#     # print_func_name(say_goodbye)
#     print("goodbye")
#
# def print_func_name(func):
#     # 包装新旧功能
#     def wrapper():
#         # 增加的新功能
#         print(func.__name__)
#         # 旧功能
#         func()
#
#     return wrapper # 返回包装器
#
# say_hello = print_func_name(say_hello)
# say_goodbye = print_func_name(say_goodbye)
#
# say_hello()
# say_goodbye()

# 缺点:调用者完成包装新旧方法的任务.
# 解决:应该有定义者完成.

# def print_func_name(func):
#     # 包装新旧功能
#     def wrapper():
#         # 增加的新功能
#         print(func.__name__)
#         # 旧功能
#         func()
#
#     return wrapper # 返回包装器
#
# @print_func_name # say_hello = print_func_name(say_hello)
# def say_hello():
#     print("hello")
#     return "哈哈"
#
# @print_func_name
# def say_goodbye():
#     print("goodbye")
#
# #---------以上是定义者--以下是调用者-----------------
# say_hello()
# say_goodbye()

# 缺点:旧功能的返回值不能被客户端代码接受到.
#      旧功能的参数,客户端代码也无法传入.

# def print_func_name(func):
#     # 包装新旧功能
#     def wrapper(name):
#         # 增加的新功能
#         print(func.__name__)
#         # 旧功能
#         return func(name)
#
#     return wrapper # 返回包装器

# 缺点:包装器不能适应所有的旧功能参数
def print_func_name(func):
    # 包装新旧功能
    def wrapper(*args,**kwargs):
        # 增加的新功能
        print(func.__name__)
        # 旧功能
        return func(*args,**kwargs)

    return wrapper # 返回包装器

@print_func_name # say_hello = print_func_name(say_hello)
def say_hello(name):
    print(name,"hello")
    return "哈哈"

@print_func_name
def say_goodbye(name,age):
    print(age,name,"goodbye")

#---------以上是定义者--以下是调用者-----------------
print(say_hello("张无忌"))
say_goodbye("赵敏",25)

  代码7:

  

"""
    练习:使用装饰器实现:
       为两个已有功能(进入后台,删除订单),增加新功能(验证权限). 
"""

# 1. 定义装饰器(新功能 + 旧功能)

def verify_permissions(func):
    def wrapper(*args, **kwargs):
        print("验证权限")
        return func(*args, **kwargs)
    return wrapper

# 2. 拦截调用
@verify_permissions
def enter_background(loginId,pwd):
    print(loginId,pwd)
    print("进入后台系统.....")

@verify_permissions
def delete_order(order_id):
    print("删除%d订单..."%order_id)


enter_background("zs",123)
delete_order(101)

  代码8:

  

"""
    练习2:为两个已有功能(存款取款),添加新功能(验证账户)
    
"""
def verify_accont(func):
    def wrapper(*args,**kwargs):
        print("验证账户")
        return func(*args,**kwargs)
    return wrapper

#deposit = verify_accont(deposit)
@verify_accont
def deposit(money):
    print("存款:",money)

@verify_accont
def withdraw():
    print("取钱")
    return 10000

deposit(5000)
print(withdraw())

  代码9:

  

"""
    练习:
       为学生的学习方法,添加新功能(打印执行时间)
"""

import time


def print_execute_time(func):
    def wrapper(*args, **kwargs):
        # 记录执行前的时间
        start_time = time.time()
        result = func(*args, **kwargs)
        # 统计执行时间
        execute_time = time.time() - start_time
        print("执行时间是:", execute_time)
        return result

    return wrapper


class Student:
    def __init__(self, name):
        self.name = name

    @print_execute_time
    def study(self):
        print("开始学习喽")
        time.sleep(2)  # 睡眠两秒 模拟学习了两秒


s01 = Student("无忌")
s01.study()

    

原文地址:https://www.cnblogs.com/yuxiangyang/p/10770241.html