多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ## 1. 可变参数 > 1. 参数以一个*号开头的代表着一个任意长度的元组(tuple),列表,变量,可以接收连续一串参数,如上面代码里传的是1,2,3,你可以更多。 > 2. 参数以两个*号开头的代表着一个字典,参数的形式是“key=value”,接受连续任意多个参数。 1. 实例 ~~~ def foo(x,a=1,**keys): print(x) print(a) print(keys) if __name__ == '__main__': foo("xxx",a="a",b="b",c="c") ~~~ 结果 ~~~ xxx a {'b': 'b', 'c': 'c'} ~~~ 2. 变参2 ~~~ class test: def param(self,x,*l,**t): print(x) print("l:",l) print("t:",t) print("name:",t.get('name')) if __name__ == '__main__': t1 = test() s = [1,'dd'] t1.param(12,s,'dailin',name='dailin',age=25) ~~~ 得到 ~~~ 12 l: ([1, 'dd'], 'dailin') t: {'name': 'dailin', 'age': 25} name: dailin ~~~ ## 2. 闭包 1. 什么是闭包 内部函数对外部函数作用域内变量的引用(非全局变量),则成内部函数为闭包。 2. 例如 ~~~ def test(number): def test_in(number_in): print("in test_in 函数, number_in is %d"%number_in) return number+number_in return test_in ~~~ ~~~ In [11]: ret = test(20) # 返回test_in函数(引用外部函数的number变量) ...: print(ret(100)) # 调用ret函数 ...: print(ret(200)) in test_in 函数, number_in is 100 120 in test_in 函数, number_in is 200 220 ~~~ ~~~ def line_conf(a, b): def line(x): return a*x + b return line line1 = line_conf(1, 1) line2 = line_conf(4, 5) print(line1(5)) print(line2(5)) ~~~ ~~~ 这个例⼦中, 函数line与变量a,b构成闭包。 在创建闭包的时候, 我们通过line_conf的参数a,b说明了这两个变量的取值, 这样, 我们就确定了函数的最终形式(y = x + 1和y = 4x + 5)。 我们只需要变换参数a,b, 就可以获得不同的 直线表达函数。 由此, 我们可以看到, 闭包也具有提⾼代码可复⽤性的作⽤ ~~~ ## 3. 装饰器 ### 1. 什么是装饰器 > * 写代码要遵循 开放封闭 原则, 虽然在这个原则是⽤的⾯向对象开发, 但是也适⽤于函数式编程, 简单来说, 它规定已经实现的功能代码不允许被修改, > 但可以被扩展, 即: > 封闭: 已实现的功能代码块 > 开放: 对扩展开发 ~~~ def w1(func): def inner(): print("w1") func() return inner @w1 def f1(): print('f1') if __name__ == '__main__': f1() ~~~ 结果 w1 f1 ~~~ python解释器就会从上到下解释代码, 步骤如下: 1. def w1(func): ==>将w1函数加载到内存 2. @w1 ~~~ 此时,没有发生调用,解释器仅仅会解释这些代码,内部代码不会被执行(未调用) * @w1内部会执⾏⼀下操作: 1. 调用装饰器 被@w1标识的函数f1,会被作为w1函数的参数,即@w1等价于w1(f1),内部回去执行w1的代码: 返回对f1装饰后的函数 ~~~ def inner(): #验证 1 #验证 2 #验证 3 f1() # func是参数, 此时 func 等于 f1 return inner# 返回的 inner, inner代表的是函数, ⾮执⾏函数 ,其实 ~~~ 2. 将装饰后的函数,返回给源函数 将执⾏完的w1函数返回值 赋值 给@w1下⾯的函数的函数名f1 即将w1的返回值再重新赋值给 f1 此时f1指向装饰后的函数inner,调用f1,就是调用inner 3. 装饰器的套用 ~~~ def makeBold(fn): def wrapped(): return "<b>" + fn() + "</b>" return wrapped #定义函数: 完成包裹数据 def makeItalic(fn): def wrapped(): return "<i>" + fn() + "</i>" return wrapped @makeBold def test1(): return "hello world-1" @makeItalic def test2(): return "hello world-2" @makeBold @makeItalic def test3(): return "hello world-3" print(test1()) print(test2()) print(test3()) ~~~ 结果(先调用下边的装饰器) ~~~ <b>hello world-1</b> <i>hello world-2</i> <b><i>hello world-3</i></b> ~~~ 3. 带参数的装饰器 ~~~ from time import ctime, sleep def timefun(func): # 这里调用接收一个函数,写明就行不带参数啥的 def wrappedfunc(a, b): # 这里和源函数一样(两个参数) print("%s called at %s"%(func.__name__, ctime())) print(a, b) func(a, b) return wrappedfunc @timefun def foo(a, b): print(a+b) if __name__ == '__main__': foo(3,5) sleep(2) foo(2,4) ~~~ 结果 ~~~ foo called at Mon Oct 30 09:40:35 2017 3 5 8 foo called at Mon Oct 30 09:40:37 2017 2 4 6 ~~~ 4. 变长参数 ~~~ from time import ctime, sleep def timefun(func): def wrappedfunc(*args, **kwargs): print("%s called at %s"%(func.__name__, ctime())) func(*args, **kwargs) return wrappedfunc @timefun def foo(a, b, c): print(a+b+c) @timefun def foo1(a,b,c,d): print(a + b + c+d) if __name__ == '__main__': foo(3,5,7) sleep(2) foo(2,4,9) foo1(1,2,3,4) ~~~ ### 2. 装饰器的作用 1. 引⼊⽇志 2. 函数执⾏时间统计 3. 执⾏函数前预备处理 4. 执⾏函数后清理功能 5. 权限校验等场景 6. 缓存