博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python-Decorator
阅读量:5977 次
发布时间:2019-06-20

本文共 2607 字,大约阅读时间需要 8 分钟。

面向对象思想的实现

class Averager():    def __init__(self):    self.series = []    def __call__(self, new_value):        self.series.append(new_value)        total = sum(self.series)        return total/len(self.series)
>>> avg(10)10.0>>> avg(11)10.5>>> avg(12)11.0

函数式编程思想的实现

def make_averager():    series = []    def averager(new_value):        series.append(new_value)        total = sum(series)        return total/len(series)    return averager
>>> avg = make_averager()>>> avg(10)10.0>>> avg(11)10.5>>> avg(12)11.0

nonlocal关键字

def make_averager():    count = 0    total = 0    def averager(new_value):        count += 1        total += new_value        return total / count    return averager
>>> avg = make_averager()>>> avg(10)Traceback (most recent call last): ...UnboundLocalError: local variable 'count' referenced before assignment>>>

The problem is that the statement count += 1 actually means the same as count = count + 1, when count is a number or any immutable type. So we are actually assigning to count in the body of averager, and that makes it a local variable. The same problem affects the total variable.

We did not have this problem in the example because we never assigned to the series list, we only called series.append and invoked sum and len on it. So we took advantage of the fact that lists are mutable. But with immutable types like numbers, strings, tuples etc., all you can is read, but never update. If you try to rebind them, as in count = count + 1, then you are implicitly creating a local variable count. It is no longer a free variable, therefore it is not saved in the closure.

To work around this the nonlocal declaration was introduced in Python 3. It lets you flag a variable as a free variable even when it is assigned a new value within the function. If a new value is assigned to a nonlocal variable, the binding stored in the closure is changed.

def make_averager():    count = 0    total = 0    def averager(new_value):        nonlocal count, total        count += 1        total += new_value        return total / count    return averager

带参数的装饰器

def use_logging(level):    def decorator(func):        def wrapper(*args, **kwargs):            if level == "warn":                logging.warn("%s is running" % func.__name__)            elif level == "info":                logging.info("%s is running" % func.__name__)            return func(*args)        return wrapper    return decorator@use_logging(level="warn")def foo(name='foo'):    print("i am %s" % name)foo()

Stacked decorators

@d1@d2def f():    print('f')# equivalent todef f():    print('f')f = d1(d2(f))

转载地址:http://tupox.baihongyu.com/

你可能感兴趣的文章
iOS中EXC_BAD_ACCESS解决办法
查看>>
什么样的技术人员更容易接到软件开发项目?(论干私活儿)
查看>>
grep,egrep及元字符和posix字符集
查看>>
inotify 实时的Linux文件系统事件监控
查看>>
自动装箱与自动拆箱的一些问题
查看>>
配置CentOS的网络环境
查看>>
MongoDB对指定键进行排序
查看>>
paramiko-exec.py——利用paramiko远程执行命令
查看>>
android应用植入广告SDK,获取广告收入
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
Springboot2.1.3 + redis 实现 cache序列化乱码问题
查看>>
各种资源思科、gns3……
查看>>
oracle基础之工具系列(持续更新中,,)
查看>>
C 过渡 C++ 1
查看>>
JSP自定义标签渲染时报Illegal to flush错误
查看>>
压力测试与提升服务器能力的几个方法
查看>>
undo详解
查看>>
12.super关键字
查看>>
封装+构造方法小例子
查看>>