zoukankan      html  css  js  c++  java
  • 闭包和装饰器

    内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。

     

     

    一:. *args **kwargs

    1. python函数传递参数的方式有两种:

     

    位置参数(positional argument)

    关键词参数(keyword argument)

    *args 与 **kwargs 的区别,两者都是 python 中的可变参数:

     

    *args 表示任何多个无名参数,它本质是一个 tuple(即 args是一个tuple)

    **kwargs 表示关键字参数,它本质上是一个 dict(kwargs是一个dict)

    如果同时使用 *args 和 **kwargs 时,必须 *args 参数列要在 **kwargs 之前。

      

     

     

    2. 函数实参

    如果函数的形参是定长参数,也可以使用 *args 和 **kwargs 调用函数,类似对元组和字典进行解引用(解包)

     

    但是**kwargs 无法进行打印,他输出的值类似 (A="a",B="b"),但是可以作为函数的入参,fun(**kwargs)

     

    3.序列解包

    序列解包 往期博客有写过,这里只列出一个例子,序列解包没有 **。

    备注: * 可以进行单独使用,也可以放在函数的实参中解包使用

    ** 不可以单独使用,可以放在函数的实参中解包使用;

     

    def func(*args,**kwargs):

    return args,kwargs

    print(func(**{"a":1,"b":2})) # ((), {'a': 1, 'b': 2})

    print(func(*[1,2,3,4])) # ((1, 2, 3, 4), {})

    print(*[1,2,3,4]) # 1 2 3 4

    print(**{"a":1,"b":2}) # 抛错

     

     

     

     

     

    二: 装饰器(函数实现装饰器和类实现装饰器

    1. 不带参数

     

    函数实现装饰器:

     

    import functools

    def log(f):

    def _func(*args,**kwargs):

    print("call ---",f.__name__)

    return f(args,kwargs)

    return _func

    @log

    def factorial(n):

    return functools.reduce(lambda x,y: x*y, range(1, n+1))

    print(factorial(10))

     

     

    类实现装饰器:

     

    import functools

    class log:

    def __call__(self, f):

    def _func(*args, **kwargs):

    print("call ---", f.__name__)

    return f(*args,**kwargs)

    return _func

    @log()

    def factorial(n):

    return functools.reduce(lambda x,y: x*y, range(1, n+1))

     

     

    2. 带参数得装饰器

     

    import functools

    import time

    def performance(mes):

    def _performance(f):

    def _func(*args, **kwargs):

    print(time.time())

    print(f(*args, **kwargs),mes)

    # return

    return _func

    return _performance

    @performance("info")

    def factorial(n):

    return functools.reduce(lambda x, y: x * y, range(1, n + 1))

    # factorial = performance("info")(factorial)

    print(factorial(10))

     

     

    通过类实现:

     

    import functools

    class log:

    def __init__(self,info):

    self.info = info

    def __call__(self, f):

    def _func(*args, **kwargs):

    print("call ---", f.__name__,self.info)

    return f(*args,**kwargs)

    return _func

    @log("info")

    def factorial(n):

    return functools.reduce(lambda x,y: x*y, range(1, n+1))

    print(factorial(10))

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式
    java如何得到GET和POST请求URL和参数列表
    Tomcat处理HTTP请求源码分析(下)
    Tomcat处理HTTP请求源码分析(上)(转)
    tomcat免重启随意更改java代码 提高开发效率
    ServletRequest中getReader()和getInputStream()只能调用一次的解决办法
    Spring MVC之@RequestParam @RequestBody @RequestHeader 等详解
    Tomcat处理HTTP请求源码分析(上)
    Drupal views中实现两列布局
    (转) 转换Drupal7模块到Drupal8
  • 原文地址:https://www.cnblogs.com/wenshu/p/12257973.html
Copyright © 2011-2022 走看看