Long Way To Go 之 Python 4
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Long Way To Go 之 Python 4相关的知识,希望对你有一定的参考价值。
装饰器decorator
(“器”代表的是函数)
定义:本质是函数
作用:用来装饰其他函数 in other words,为其他函数添加附加功能
(eg. 假如程序已上线,如果想新增功能,但是又不能改源代码)
原则:
1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方试
组成:高阶函数+嵌套函数 --> 装饰器
Q: 高阶\嵌套函数是个什么鬼???
高阶函数:
1.把一个函数当做实参传给另一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
import time def bar(): time.sleep(3) print("in the bar") def test1(func): start_time = time.time() func() # run bar() stop_time = time.time() print("the func run time is %s"%(stop_time -start_time)) # 统计的是bar的运行时间 test1(bar) # func = bar 所以可以进行func() 传的内存地址 test1(bar()) # 把bar()的返回值传进去了 传的返回值 # BUT !调用方式变了,不是装饰器
2.返回值中包含函数名(不修改函数的调用方式)
import time def bar(): time.sleep(3) print("in the bar") def test2(func): print(func) # 打印func的内存地址,也就是bar的内存地址 return func # return bar的内存地址 bar = test2(bar) bar() # run bar
嵌套函数:
在一个函数的函数体内用def去申请另一个函数
#嵌套函数 def foo(): print("in the foo") def bar(): # 相当于局部变量,所以不能在外面直接调用bar(),所以要写在里面 print("in the bar") bar() foo() # 这个不是函数的嵌套,这叫函数的调用 def test1(): test2() test1()
EXAMPLE 1
优化(@timmer)
def timer(func): #timer(test1) 把test1的内存地址传给func,func = test1 def deco(): start_time = time.time() func() # run test1 stop_time = time.time() print("the func run time is %s"%(start_time-stop_time)) return deco # 返回这个函数的内存地址 @timer # 这就相当于 test1 = timer(test1) def test1(): time.sleep(3) print("in the test1") @timer def test2(): time.sleep(3) print("in the test2") test1() test2() # 其实调用的是deco这个函数,因为timer(test1)的返回值是deco的内存地址
优化(调用时传入多个参数)
def timer(func): #timer(test1) 把test1的内存地址传给func,func = test1 def deco(*args,**kwargs): start_time = time.time() func(*args,**kwargs) # run test1 stop_time = time.time() print("the func run time is %s"%(start_time-stop_time)) return deco # 返回这个函数的内存地址 @timer # 这就相当于 test1 = timer(test1) = deco def test1(): time.sleep(1) print("in the test1") @timer # test2 = timer(test2) = deco # test2() = deco() 所以在deco里加args def test2(name,age): print("test2:",name,age,) test1() test2("alex",22)
EXAMPLE 2 !!
import time user,passwd = "alex","abc123" def auth(auth_type): print("auth func:",auth_type) def outer_wrapper(func): def wrapper(*args,**kwargs): print("wrapper func args:",*args,**kwargs) if auth_type =="local": username = input("username:").strip() password = input("password:").strip() if user == username and passwd == password: print("\033[32;1mUser has passed authenfication\033[0m") res = func(*args,**kwargs) # return from home print("------after authenficaiton") return res else: exit("\033[31;1mInvalid username or password\033[0m") elif auth_type == "ladp": print("毛线ldap,不会------") return wrapper return outer_wrapper def index(): # 首页 print("welcome to index page") @auth(auth_type = "local") # 本地认证 & home = wrapper() def home(): # 用户登录后的首页 print("welcome to home page") return "from home" @auth(auth_type = "ldap") # 远程认证 def bbs(): # 论坛 print("welcome to bbs page") index() print(home()) # return None 如果没有return func()的话 bbs()
ps:
函数及变量
# 没问题 def bar(): print("in the bar") def foo(): print("in the foo") bar() foo() # bar定义到下面也是可以运行的 def foo(): print("in the foo") bar() def bar(): print("in the bar") foo() # 会报错,因为函数和变量一样,是先定义,在调用。所以会报错 def foo(): print("in the foo") bar() foo() def bar(): print("in the bar")
生成器generator
原理:只有在调用时才会生成相应的数据(假如一个大数据,只循坏了前5次,那么后面的数据是没有准备好的)
作用:省内存
特点:生成器只记住当前位置(不管前后),不能后退回返,也不能跳着走
只有一个next方法: __next__()
ps:
列表生成式
>>>print([i*2 for i in range(10)]) [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] >>> >>>[func(i) for i in range(10)] # 传函数也可以
以上是关于Long Way To Go 之 Python 4的主要内容,如果未能解决你的问题,请参考以下文章
Go实战--实现一个自己的网络请求日志httplogger(The way to go)