• python返回函数+匿名函数+装饰器+偏函数


    函数作为返回值

    可变参数的求和

    可以不返回求和的结果,而是返回求和的函数:
    不需要立刻求和,而是在后面的代码中,根据需要再计算

    def sum_nums(*args):
        sum = 0
        for i in args:
            sum = sum + i
        return sum
    def lazy_sum(*args):
        def sum_nums():
            ax = 0
            for i in args:
                ax = ax + i
            return ax
        return sum_nums
    if __name__ == '__main__':
        print(sum_nums(1, 2, 3, 4, 5)) #15
        print(lazy_sum(1,2,3,4,5)) #<function lazy_sum.<locals>.sum_nums at 0x000001D547F8B6A8> 返回的是函数  运行的时候需要调用函数
        f1 = lazy_sum(1, 3, 5, 7, 9)
        f2 = lazy_sum(1, 3, 5, 7, 9)
        print(f1==f2)
        #False
    

    闭包

    注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。另一个需要注意的问题是,返回的函数并没有立刻执行,而是直到调用了f()才执行。

    def fun():
        print("hello")
        def fun1():            # 作用域 运行时存活 函数执行期间
            print("world")   #想让fun1 调用 需要用 return fun1()  / fun1
    

    https://www.bilibili.com/video/av18586448?from=search&seid=6307915518193049229

    def count():
        fs = []
        for i in range(1, 4):
            def f():
                 return i*i
            fs.append(f)
        return fs
    
    f1, f2, f3 = count()      #9 9 9 经过初步的检验得出 存到 fs 是 三个 f 的 地址 已经有进行运行 所以 f1 f2 f3 只是让里面的函数进行运行
    #ValueError: too many values to unpack (expected 2) 需要有三个函数输入并同时返回三个函数,等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9
    #闭包
    def count():
        def fun1(j):
            def fun2():
                return j*j
            print(j,fun2())
            return fun2
        ls = []
        for i in range(1,4):
            ls.append(fun1(i))
        return ls
    
    if __name__ == '__main__':
        a,b,c = count()
        print(a())
        print(b())
        print(c())
    '''
    1 1
    2 4
    3 9
    1
    4
    9
    '''
    #计数器
    def createCounter():
    	i = 0
    	def counter():
    		nonlocal i
    		i += 1
    		return i
    	return counter
    

    匿名函数

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

    装饰器

    增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
    函数对象有一个__name__属性,可以拿到函数的名字
    https://www.bilibili.com/video/av25698102/
    https://www.jianshu.com/p/98f7e34845b5
    https://v.youku.com/v_show/id_XNDMwNjczNjExMg==.html

    import time
    # 时间未加装饰器
    def is_prime(x):
        if x < 2 :
            return False
        elif x == 2 :
            return True
        else :
            for i in range(2 , x):
                if x % i == 0:
                    return False
            return True
    
    def print_nums():
        a = time.time()
        for i in range(2 ,10000 ):
            if is_prime(i):
                print(i)
        b = time.time()
        print(b-a)
    
    if __name__ == '__main__':
        print_nums()
    
    

    改成时间的装饰器

    
    def display_time(func):
        def wrapper():       #包装:wrapper   其实这里可以替代为其他的名字
            a = time.time()
            func()           # 只是装饰器就是这样的结构
            b = time.time()
            print(b - a)
        return wrapper     # 对其wrapper 这里返回wrapper  如果下面 print_nums不加括号 wrapper要加  反之不加
    
    @display_time
    def print_nums():
        for i in range(2 ,10000 ):
            if is_prime(i):
                print(i)
    
    
    if __name__ == '__main__':
        print_nums()
    

    继续变形

    def display_time(func):
        def wrapper():
            a = time.time()
            result = func()              # 星星
            b = time.time()
            print(b - a)
            return result
        return wrapper
    
    @display_time
    def print_nums():
        count = 0
        for i in range(2 ,10000 ):
            if is_prime(i):
                count = count+1
        return count                  # 星星 返回除去给func 后给 result
    
    
    if __name__ == '__main__':
        print(print_nums())            #调用即运行 后输出result 给 wrapper                就不会输出none
    

    加参数的操作

    def display_time(func):
        def wrapper(*args):                   # 星星
            a = time.time()
            result = func(*args)              # 星星
            b = time.time()
            print(b - a)
            return result
        return wrapper
    
    @display_time
    def print_nums(nums):                  # 星星
        count = 0
        for i in range(2 ,nums ):          # 星星 
            if is_prime(i):
                count = count+1
        return count
    
    
    if __name__ == '__main__':
        print(print_nums(10000))            #调用即运行 后输出result 给 wrapper
    

    wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用

    三层嵌套


    import functools
    def log (func):
        #@functools.wraps(func)  有得话 house 无则 wrapper  消除装饰器的副作用
        def wrapper():
            return func()
        return wrapper
    
    @log
    def house():
        print(house.__name__)
        
    house()
    
    小结
    在面向对象(OOP)的设计模式中,decorator被称为装饰模式。OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator。Python的decorator可以用函数实现,也可以用类实现。
    decorator可以增强函数的功能,定义起来虽然有点复杂,但使用起来非常灵活和方便。
    @functools.wraps(func) 消除副作用
    

    偏函数

    Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)

    • int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换 int('123456')
    • 但int()函数还提供额外的base参数,默认值为10。如果传入base参数,就可以做N进制的转换 int('123456 ' , base = 8) / ,16
      functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数:
    import  functools
    int2 = functools.partial(int , base = 2)
    print(int2('11101'))
    


    当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

  • 相关阅读:
    幻灯片效果
    国外空间乱码的解决方法
    图片自动适应
    css圆角效
    iframe自适应兼容
    css圆角
    图片自动适应2
    JQuery实现智能输入提示(仿机票预订网站)
    AppDiag类
    c# 渐变算法
  • 原文地址:https://www.cnblogs.com/cznczai/p/11345534.html
Copyright © 2020-2023  润新知