网站国际化建设方案,设计网红店铺,安卓app怎么开发,南通网站设计公司分类目录#xff1a;《系统学习Python》总目录 如果我们没有在使用Python3.X并因此无法利用一条nonlocal语句#xff0c;或者我们希望代码具有可移植性#xff0c;能在Python3.X和Python2.X上同时工作一一我们仍然能够针对某些可改变的状态使用函数属性来避免使用全局变量和…分类目录《系统学习Python》总目录 如果我们没有在使用Python3.X并因此无法利用一条nonlocal语句或者我们希望代码具有可移植性能在Python3.X和Python2.X上同时工作一一我们仍然能够针对某些可改变的状态使用函数属性来避免使用全局变量和类。在Python2.1之后的所有Python版本中我们可以把任意属性分配给函数并使函数附带上它们这使用func.attrvalue就可以实现。因为工厂函数在每一次调用时都创建一个新函数所以其属性就成为了与调用息息相关的状态。此外你只需针对必须改变的状态变量使用这一技巧外层作用域引用仍被保留并且正常地工作。
在我们的示例中可以直接对状态使用wrapper.calls。如下的代码与前面的nonlocal版本运行后是一样的因为每个被装饰函数都再次拥有了自己的计数器但是这个版本也可以在Python2.X下运行
def tracer(func):def wrapper(*args, **kwargs):wrapper.calls 1print(call %s to %s % (wrapper.calls, func.__name__))return func(*args, **kwargs)wrapper.calls 0return wrappertracer
def spam(a, b, c):print(a b c)tracer
def eggs(s, y):print(x ** y)span(1, 2, 3)
span(a4, b5, c6)
eggs(2, 16)
eggs(4, y4)因为名称wrapper保持在外层tracer函数的作用域中这种方法才有效。当我们随后递增wrapper.calls时并不是修改名称wapper本身因此不需要任何nonlocal声明。这一版本在任一Python系列中都可运行。
这种方案几乎作为一个脚注来介绍因为它可能比Python3.X中的nonlocal要晦涩难解得多并且可能留待其他方案无济于事的情况下使用更好。然而函数属性也拥有足够多的优点。其中之一是它们允许从装饰器代码的外部访问保存的状态nonlocal只能从嵌套函数自身的内部看到可是函数属性则有更广泛的可见性。另外一个优点就是它们的可移植性要强得多这一方案在python2.X中也能工作因而是版本中立的。
由于可更改的状态与使用上下文相关联因此它们等同于外层作用域的非局部变量。照常从多种工具中进行选是编程任务的天生一部分。由于装饰器往往意味着可调用对象的多个层级因此我们可以将外层作用域、带有属性的类以及函数属性等与函数进行组合以实现各种各样的编程结构。正如我们稍后将见到的这有时候可能比我们所期待的要微妙一一每个被装饰的函数应该有自己的状态并且每个被装饰的类以及该类生成的实例也应有自己的状态。
实际上正如后面的文章将详细讲述的如果我们也想要对一个类级别的方法应用函数装饰器必须小心Python在作为可调用类的实例对象编写的装饰器和作为函数编写的装饰器之间的区分。
参考文献 [1] Mark Lutz. Python学习手册[M]. 机械工业出版社, 2018.