zoukankan      html  css  js  c++  java
  • 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()

        

  • 相关阅读:
    python imageai 对象检测、对象识别
    flask跨域请求三行代码搞定
    图片压缩-KMeans
    电影天堂
    python 时间操作
    时间HTML
    3D滚动效果
    tensorflow基础
    studio显示Surface: getSlotFromBufferLocked: unknown buffer: 0xa2a58be0
    解决github访问慢和clone慢解决方案
  • 原文地址:https://www.cnblogs.com/yuxiangyang/p/10770241.html
Copyright © 2011-2022 走看看