玩蛇网提供最新Python编程技术信息以及Python资源下载!

cookbook书中关于装饰器的源码里,这个参数是怎么传递的?

不是很明白这里的参数是如何传递的

from functools import wraps, partial
import logging
# Utility decorator to attach a function as an attribute of obj
def attach_wrapper(obj, func=None):
    if func is None:
        return partial(attach_wrapper, obj)
    setattr(obj, func.__name__, func)
    return func

def logged(level, name=None, message=None):
    '''
    Add logging to a function. level is the logging
    level, name is the logger name, and message is the
    log message. If name and message aren't specified,
    they default to the function's module and name.
    '''
    def decorate(func):
        logname = name if name else func.__module__
        log = logging.getLogger(logname)
        logmsg = message if message else func.__name__

        @wraps(func)
        def wrapper(*args, **kwargs):
            log.log(level, logmsg)
            return func(*args, **kwargs)

        # Attach setter functions
        @attach_wrapper(wrapper)
        def set_level(newlevel):
            nonlocal level
            level = newlevel

        @attach_wrapper(wrapper)
        def set_message(newmsg):
            nonlocal logmsg
            logmsg = newmsg

        return wrapper

    return decorate

# Example use
@logged(logging.DEBUG)
def add(x, y):
    return x + y

@logged(logging.CRITICAL, 'example')
def spam():
    print('Spam!')

没看明白set_level用attach_wrapper装饰的时候, 为什么会有obj与func两个参数

from functools import wraps, partial
import logging
# Utility decorator to attach a function as an attribute of obj
def attach_wrapper(obj, func=None):
    if func is None:
        return partial(attach_wrapper, obj)
    setattr(obj, func.__name__, func)              # 工具, 把属性绑定到特定的obj上
    return func

def logged(level, name=None, message=None):
    '''
    Add logging to a function. level is the logging
    level, name is the logger name, and message is the
    log message. If name and message aren't specified,
    they default to the function's module and name.
    '''
    def decorate(func):
        logname = name if name else func.__module__
        log = logging.getLogger(logname)
        logmsg = message if message else func.__name__

        @wraps(func)
        def wrapper(*args, **kwargs):
            log.log(level, logmsg)
            return func(*args, **kwargs)

        # Attach setter functions
        @attach_wrapper(wrapper)       # 1 辅助函数1, 这个属性会绑定到被修饰的函数上
        def set_level(newlevel):
            nonlocal level
            level = newlevel

        @attach_wrapper(wrapper)       #2 辅助函数2, 这个属性也会绑定到被修饰的函数上
        def set_message(newmsg):
            nonlocal logmsg
            logmsg = newmsg

        return wrapper

    return decorate

# Example use
@logged(logging.DEBUG)
def add(x, y):
    return x + y

@logged(logging.CRITICAL, 'example')
def spam():
    print('Spam!')
  1. 看我加的中文注释

理解这段代码, 需要

  1. 明白在Python, 所有东西都是对象, 函数也是( 比如 数字2, 也是对象, 我们也可以对它绑定任何东西 ), 所以我们可以任意给函数绑定任何东西

In [1]: def func(a, b):
   ...:     return a+b
   ...: 

In [2]: func.attached_func1 = lambda _x: _x * _x

In [3]: func.attached_func1
Out[3]: <function __main__.<lambda>>
  1. 明白作者为何要这样写

    • 给函数添加日志

    • 这远远不够, 我们希望函数被我们装饰之后, 添加我们希望的属性上去

玩蛇网文章,转载请注明出处和文章网址:https://www.iplaypy.com/wenda/wd13823.html

相关文章 Recommend

玩蛇网Python互助QQ群,欢迎加入-->: 106381465 玩蛇网Python新手群
修订日期:2017年05月14日 - 11时26分48秒 发布自玩蛇网

您现在的位置: 玩蛇网首页 > Python问题解答 > 正文内容
我要分享到:

必知PYTHON教程 Must Know PYTHON Tutorials

必知PYTHON模块 Must Know PYTHON Modules