@修饰符 二

修饰符基础——闭包

什么是闭包呢?标准的概念大家可以看wikipedia上的解释点击打开链接   举个例子:

[python] view plain copy

  1. def do_add(base):
  2. def add(increase):
  3. return base + increase
  4. return add

do_add函数里嵌套了一个内层函数add,这个内层函数就是一个闭包,其实可以也不用管这个“闭包”的概念,先来看下这种模式解决些什么问题.


用do_add函数:a =
do_add(23),由于内层的函数add里的逻辑用到了do_add函数的入参,而这时这个入参base绑定了值23,由于do_add函数返回的是
函数add,所以这时的a其实就是内部的add绑定了23的函数add;同理可知,b
=
do_add(44),这里的b就是内部add绑定了44的函数add,a和b这两个add函数是不相同的,因为内部add绑定的值不同,只是两个函数的
模板相同罢了,这时我们执行a(100)得到结果是123,b(100)得到结果是144。这样做有什么用呢?其实可以这样看:我们可以把a =
do_add(23)和b =
do_add(44)看成是配置过程,23和44是配置信息,a(100)和b(100)根据不同的配置获得不同的结果,这样我们就可以解决开发中“根据
配置信息不同获得不同结果”的问题

而修饰符实际上就是闭包一种形式,只是配置过程参数是所修饰的一个函数,并且用@符号代替了a=do_add(23)这样的配置方式,下面看一下修饰符的用法

修饰符用法

修饰符无参数,原函数无参数

[python] view plain copy

  1. import time
  2. def timeit(func):
  3. def wrapper():
  4. start = time.clock()
  5. func()
  6. end =time.clock()
  7. print ‘used:‘, end - start
  8. return wrapper
  9. @timeit
  10. def foo():
  11. print ‘in foo()‘
  12. foo()

如上代码:对所修饰函数运行时间的进行统计,最后修饰过的 foo()  等价于 foo=timeit(foo) 而timeit返回wrapper,归根到底真正执行的是wrapper

在实际应用中,函数很少没有参数,所以我们看看foo有参数的情况下,修饰符怎么用

修饰符无参数,原函数有参数

[python] view plain copy

  1. import time
  2. def timeit(func):
  3. def wrapper(args):
  4. start = time.clock()
  5. func(args)
  6. end =time.clock()
  7. print ‘used:‘, end - start
  8. return wrapper
  9. @timeit
  10. def foo(arg):
  11. print ‘in foo(),arg is‘ + arg
  12. foo("aaaaa")

上述过程可以简化如下:

[decorated]
foo(‘aaaaa’)   =>   timeit(foo)(‘aaaaa’)  =>  wrapper(‘aaaaa’)  =>  [real]
foo(‘aaaaa’)

如果修饰符函数也有参数,又怎么用呢?

修饰符有参数,原函数有参数

[python] view plain copy

  1. import time
  2. def timeit(s):
  3. def wrapper1(func)
  4. def wrapper2(args):
  5. print "the decorator‘s arg is"+s
  6. start = time.clock()
  7. func(args)
  8. end =time.clock()
  9. print ‘used:‘, end - start
  10. return wrapper2
  11. return wrapper1
  12. @timeit(s="hello")
  13. def foo(arg):
  14. print ‘in foo(),arg is‘ + arg
  15. foo("aaaaa")
  16. 同理,就是多加了一层闭包。

应用多个修饰符

这个记住一个结论就好了,就是修饰符从离原函数最近的开始包裹,最外层的修饰符最后包裹

应用举例——Fibonacci数列


[python] view plain copy

  1. def memoize(f):
  2. cache = {}
  3. def helper(x):
  4. if x not in cache:
  5. cache[x] = f(x)
  6. return cache[x]
  7. return helper
  8. @memoize()
  9. def fib(n):
  10. if n in (0, 1):
  11. return n
  12. else:
  13. return fib(n - 1) + fib(n - 2)

原文地址:https://www.cnblogs.com/ouyangping/p/8453042.html

时间: 2024-10-10 17:57:33

@修饰符 二的相关文章

蓝鸥Unity开发基础二——课时3 访问修饰符

[蓝鸥Unity开发基础二]课时3 访问修饰符 一.访问修饰符 public --公共的,在哪里都能用 private  --私有的,只能够在当前机构体重使用,其他任何地方都不能 访问修饰符举例说明 using System; namespace Lesson_03{           struct Point2{        //public--公共的,在哪里都能用        public float x;        //private  --私有的,只能够在当前机构体重使用,其他

C#编程(二十四)----------修饰符

修饰符 修饰符即应用于类型或成员的关键字.修饰符可以指定方法的可见性,如public或private,还可以指定一项的本质,如刚发的vritual或abstract. 可见性的修饰符 修饰符 应用于 说明 public 所有类型或成员 任何代码均可以访问该项 protected 类型和内嵌类型的所有成员 只有派生的类型能访问该项 internal 所有类型或成员 只能包含它的程序集中访问该项 private 类型和内嵌类型的所有成员 只能在它所属的类型中访问该项 protected intern

Java反射(二):检测类的修饰符和类型

一个类可被若干个能影响其运行时行为的修饰符声明: 访问修饰符:public,protected,private 需要重载的修饰符:abstract 限制为只有一个实例的:static 阻止值修改:final 强制严格浮点行为:strictfp 注解 不是所有的修饰符能用在所有的类上.比如final不能修饰接口,枚举不能是abstract.java.lang.reflect.Modifier包含了所有可能修饰符的声明,它也包含用来编码由Class.getModifiers()返回的修饰符集合的方法

C# this用法系列(二) 通过this修饰符为原始类型扩展方法

定义一个静态类,类中定义静态方法,方法中参数类型前边加上this修饰符,即可实现对参数类型的方法扩展 示例如namespace Demo{ // 这里的类必须为静态类 public static class Json { // 方法为静态方法 // this修饰符后边是string类型,即为string类型扩展出了ToJson方法 public static object ToJson(this string Json) { return Json == null ? null : JsonCo

C#深入浅出 修饰符(二)

1.函数参数前的修饰符 params ,ref ,out params修饰的数据类型只能数组,用于参数不固定时:且此参数位于所有形式参数的最后: public static int GetMax(params int[]args) { if(params==null)throw new exception("请传几个值!"); int max=args[0] foreach(int i in args) { if(max<args[i]) max=args[i] } return

二、Java面向对象(5)_static修饰符

2018-04-29 树欲静而风不止 static修饰符 static修饰符表示静态的,该修饰符可以修饰字段.方法.内部类.使用该关键字修饰的内容,在面向对象中static修饰的内容是隶属于类,而不是直接隶属于对象的,所以static修饰的成员变量一般称作类成员变量,而static修饰的方法一般称作类方法. static修饰符的特点: 1)static修饰的成员(字段/方法),随着所在类的加载而加载. 当JVM把字节码加载进JVM的时候,static修饰的成员已经在内存中存在了. 2)优先于对象

二、Java面向对象(7)_封装思想——访问修饰符

2018-04-30 访问修饰符 <访问权限范围越小,安全性越高> public:表示全局的,可以在当前项目中任何地方访问 如果几个相互访问的public类分布在不用的包中,则需要导入相应public类所在的包.由于类的继承性,类所有的公有方法和变量都能被其子类继承. Java程序的main() 方法必须设置成公有的,否则,Java解释器将不能运行该类. protected:能被同一个包中的任何其他类访问,也能够被不同包中的子类访问. (protected访问修饰符不能修饰类和接口,方法和成员

(二)咋使用VUE中的事件修饰符

1,stop修饰符:阻止事件冒泡 首先我们要明确H5的事件是从内向外进行冒泡的,写一个简单的DEMO 当我们点击按钮时,事件从内向外冒泡,依次触发绑定的事件,控制台信息如下 现在我们在click后面添加.stop修饰符,如下: 我们发现再次点击按钮后,事件不再冒泡,控制台只打出 2.prevent取消默认事件 .prevent等同于JavaScript的event.preventDefault(),用于取消默认事件.比如我们页面的<a href="#">标签,当用户点击时,

JavaSE入门学习10:Java修饰符

Java语言提供了很多修饰符,主要分为以下两类: 访问修饰符 非访问修饰符 修饰符用来定义类.方法或者变量,通常放在语句的最前端.我们通过下面的例子来说明: <span style="font-size:18px;">public class className { // ... } private boolean flag; static final double weeks = 9.5; protected static final int BOXWIDTH = 42;