Python学习之路7☞装饰器
一:命名空间与作用域
1.1命名空间
局部命名空间:
def foo():
x=1
def func():
pass
全局命名空间:
import time
class ClassName:pass
def foo():pass
内键命名空间:
sum,max,min 等
python加载三个命名空间的顺序:
1.内键命名空间
2.全局命名空间:文件级别的或叫做模块级别的
3.局部命名空间:只有调用函数的时候才会加载,函数调用结束就被释放掉
1.2作用域
全局作用域:
- 同时x=1为全局变量
- x=
- def func1():
- def func2():
- def func3():
- print(x)
- func3()
- func2()
- func1()
- 输出结果
局部作用域:
- x=
- def func1():
- def func2():
- def func3():
- x=
- print(x)
- func3()
- func2()
- func1()
- 输出结果:
二:装饰器
2.1 什么是装饰器
器即函数
装饰即修饰,意指为其他函数添加新功能
装饰器定义:本质就是函数,功能是为其他函数添加新功能
2.2 实现装饰器知识储备
装饰器=高阶函数+函数嵌套+闭包
2.3 装饰器需要遵循的原则
1.不修改被装饰函数的源代码(开放封闭原则)
2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式
3装饰器是在遵守1和2的前提下,为被装饰的对象添加新功能
2.4 装饰器无参基本框架
- #这就是一个实现一个装饰器最基本的架子
- def timer(func):
- def wrapper():
- func()
- return wrapper
2.5 装饰器有参基本框架
- def timer(func):
- def wrapper(*args,**kwargs):
- func(*args,**kwargs)
- return wrapper
2.6 无参装饰器
- import time
- def timer(func): #func=最原始的index
- def warpper():
- start_time=time.time()
- func()
- end_time=time.time()
- print('run time is %s' % (end_time - start_time))
- return warpper
- #无参装饰器
- @timer #index=timer(index) 此时的index就是warpper
- def index():
- time.sleep()
- print("welcome to index")
- index()#就是在调用warpper()
- 原来的index的函数只会输出welcome to index
- 加上装饰器后;
- 输出内容为:
- welcome to index
- run time is 1.0060575008392334
2.7 有参数装饰器
- import time
- def timer(func): #func=最原始的index
- def warpper(user):
- start_time=time.time()
- func(user)
- end_time=time.time()
- print('run time is %s' % (end_time - start_time))
- return warpper
- @timer #index=timer(index) 此时的index就是warpper
- def home(user):
- time.sleep()
- print("home %s"% user)
- home('tom')#就是在调用warpper()
- 输出结果:
- home tom
- run time is 1.0000574588775635
2.8 如果传入的参数是关键字类型
- import time
- def timer(func): #func=最原始的index
- def warpper(*args,**kwargs):
- start_time=time.time()
- func(*args,**kwargs)
- end_time=time.time()
- print('run time is %s' % (end_time - start_time))
- return warpper
- @timer #index=timer(index) 此时的index就是warpper
- def home(user):
- time.sleep()
- print("home %s"% user)
- home('tom')#就是在调用warpper()
- home(user="yyp")
- #输出结果:
- home tom
- run time is 1.0000574588775635
- home yyp
- run time is 1.0000569820404053
2.9 如果原函数有返回值
- import time
- def timer(func): #func=最原始的index
- def warpper(*args,**kwargs):
- start_time=time.time()
- res=func(*args,**kwargs)
- end_time=time.time()
- print('run time is %s' % (end_time - start_time))
- return res
- return warpper
- @timer #index=timer(index) 此时的index就是warpper
- def home(user):
- time.sleep()
- return user + ' is student'
- res=home('tom')#就是在调用warpper()
- print(res)
- #输出结果:
- run time is 1.0000574588775635
- tom is student
三:闭包
闭包:本质就是一个内部函数
特点:这个内部函数必须包含对外部函数作用域(非全局作用)名字的引用
示例:
- 1 def f1():
- 2 x=1
- 3 y=2
- 4 def f2():
- 5 print(x)
- 6 print(y)
- 7 return f2
- 8
- 9 func=f1()
- 10 #func()
- 11 print(func.__closure__[0].cell_contents)#查看闭包函数的方法
- 12 print(func.__closure__[1].cell_contents)
- 13
- 14 #f2为闭包函数
- 15
- 16 输出结果:
- 17 1
- 18 2
惰性计算:啥时候用啥时候调用
- 1 from urllib.request import urlopen
- 2
- 3 def page(url):
- 4 def get():
- 5 return urlopen(url).read()
- 6 return get
- 7
- 8 baidu=page('http://www.baidu.com')
- 9 python=page('http://www.python.org')
- 10
- 11 print(baidu)
- 12 print(python)
- 13
- 14 输出结果:
- 15 <function page.<locals>.get at 0x0000000002DE6BF8>
- 16 <function page.<locals>.get at 0x0000000002DE6C80>
- 17
- 18 函数没有执行,已经传了一个参数
四:装饰器应用示例
- user_list=[
- {'name':'tom','passwd':''},
- {'name':'yyp','passwd':''},
- {'name':'sy','passwd':''},
- {'name':'ly','passwd':''},
- ]
- current_user={'username':None,'login':False}
- def auth_deco(func):
- def wrapper(*args,**kwargs):
- if current_user['username'] and current_user['login']:
- res=func(*args,**kwargs)
- return res
- username=input('用户名: ').strip()
- passwd=input('密码: ').strip()
- for index,user_dic in enumerate(user_list):
- if username == user_dic['name'] and passwd == user_dic['passwd']:
- current_user['username']=username
- current_user['login']=True
- res=func(*args,**kwargs)
- return res
- break
- else:
- print('用户名或者密码错误,重新登录')
- return wrapper
- @auth_deco
- def index():
- print('欢迎来到主页面')
- @auth_deco
- def home():
- print('这里是你家')
- def shopping_car():
- print('查看购物车啊亲')
- def order():
- print('查看订单啊亲')
- print(user_list)
- # index()
- print(user_list)
- home()
无参装饰器
- user_list=[
- {'name':'tom','passwd':''},
- {'name':'yyp','passwd':''},
- {'name':'sy','passwd':''},
- {'name':'ly','passwd':''},
- ]
- current_user={'username':None,'login':False}
- def auth(auth_type='file'):
- def auth_deco(func):
- def wrapper(*args,**kwargs):
- if auth_type == 'file':
- if current_user['username'] and current_user['login']:
- res=func(*args,**kwargs)
- return res
- username=input('用户名: ').strip()
- passwd=input('密码: ').strip()
- for index,user_dic in enumerate(user_list):
- if username == user_dic['name'] and passwd == user_dic['passwd']:
- current_user['username']=username
- current_user['login']=True
- res=func(*args,**kwargs)
- return res
- break
- else:
- print('用户名或者密码错误,重新登录')
- elif auth_type == 'ldap':
- print('巴拉巴拉小魔仙')
- res=func(*args,**kwargs)
- return res
- return wrapper
- return auth_deco
- #auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file')
- #就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数
- @auth(auth_type='ldap')
- def index():
- print('欢迎来到主页面')
- @auth(auth_type='ldap')
- def home():
- print('这里是你家')
- def shopping_car():
- print('查看购物车啊亲')
- def order():
- print('查看订单啊亲')
- # print(user_list)
- index()
- # print(user_list)
- home()
有参装饰器
Python学习之路7☞装饰器的更多相关文章
- Python学习之路6 - 装饰器
装饰器 定义:本质是函数,(装饰其他函数)就是为其他函数添加附加功能.原则:1.不能修改被装饰的函数的源代码 2.不能修改被装饰的函数的调用方式 实现装饰器的知识储备: 1.函数即“变量” 2.高阶函 ...
- Python成长之路_装饰器
一.初入装饰器 1.首先呢我们有这么一段代码,这段代码假设是N个业务部门的函数 def f1(aaa): print('我是F1业务') if aaa == 'f1': return 'ok' def ...
- python学习日记(函数--装饰器)
楔子 前提,我有一段代码(一个函数). import time def run_time(): time.sleep(0.1) print('我曾踏足山巅') 需求1:现在,我想计算这段代码的运行时间 ...
- 【Python学习之二】装饰器
装饰器 首先,给出装饰器的框架: def log(func): def wrapper(*args, **kw): print('call %s():' % func.__name__) return ...
- python 学习笔记7(装饰器)
闭包(closure)是函数式编程的重要的语法结构. 定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). def outer ...
- Python 学习笔记9(装饰器,decorator)
31 装饰器 装饰器可以对一个函数.方法或者类进行加工,是一种高级的python语法. 装饰函数 接收一个可调用对象作为输入参数,并返回一个新的可调用对象. 把函数传递给装饰器,然后增加新的功能,返回 ...
- python学习之路-day4-装饰器&json&pickle
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 一.生成器 1.列表生成式 >>> L = [x * x for x in range(10 ...
- Python学习笔记九:装饰器,生成器,迭代器
装饰器 本质是函数,装饰其他函数,为其他函数添加附加功能 原则: 1不修改原函数的源代码 2不修改原函数的调用方式 知识储备: 1函数即变量 使用门牌号的例子说明函数,调用方式与变量一致 2高阶函数 ...
- Python学习第二阶段,day1, 装饰器,生成器,迭代器
装饰器 不得不说,这是对初学者最难以理解的概念了,虽然我学过面向对象,但还是被搞懵逼了..前面还好理解,主要是后面“装饰器的装饰器”我理解不了.装饰器工厂,根据传入的参数不同去返回不同的装饰器,我不得 ...
随机推荐
- python 可迭代对象,迭代器,生成器的区别及使用
可迭代对象 可迭代对象类型:list,dict,tuple,str,set,deque等 如何判断一个对象是否是可迭代对象,可以通过dir()方法看它里面有没有__iter__方法,如果有这个方法就是 ...
- Python学习之高阶函数--嵌套函数、函数装饰器、含参函数装饰器
玩了一晚上王者,突然觉得该学习,然后大晚上的搞出来这道练习题,凌晨一点写博客(之所以这么晚就赶忙写是因为怕第二天看自己程序都忘了咋写的了),我太难了o(╥﹏╥)o 言归正传,练习题要求:构造类似京东的 ...
- struts2-result-servletAPI-获得参数-参数封装
1 结果跳转方式 转发 重定向 转发到Action 重定向到Action 2 访问servletAPI方式 2.1 原理 2.2 获得API 通过ActionContext ★★★★ 通过Servl ...
- Twitter Storm中Topology的状态
Twitter Storm中Topology的状态 状态转换如下,Topology 的持久化状态包括: active, inactive, killed, rebalancing 四个状态. 代码上看 ...
- Luogu P3106 [USACO14OPEN]GPS的决斗Dueling GPS's(最短路)
P3106 [USACO14OPEN]GPS的决斗Dueling GPS's 题意 题目描述 Farmer John has recently purchased a new car online, ...
- 实战经验 | Cassandra Java堆外内存排查经历全记录
背景 最近准备上线cassandra这个产品,同事在做一些小规格ECS(8G)的压测.压测时候比较容易触发OOM Killer,把cassandra进程干掉.问题是8G这个规格我配置的heap(Xmx ...
- 基于MaxCompute打造轻盈的人人车移动端数据平台
摘要: 2019年1月18日,由阿里巴巴MaxCompute开发者社区和阿里云栖社区联合主办的“阿里云栖开发者沙龙大数据技术专场”走近北京联合大学,本次技术沙龙上,人人车大数据平台负责人吴水永从人人车 ...
- 【python之路41】web框架
一.web框架介绍 一共有两种web框架 1.既包含socket又能逻辑处理 tornado框架 2.只能处理逻辑 Django bottle flask 二.web框架的本质 众所周知,对于所有的 ...
- ORACLE的Copy命令和create table,insert into的比较
在数据表间复制数据是Oracle DBA经常面对的任务之一,Oracle为这一任务提供了多种解决方案,SQL*Plus Copy 命令便是其中之一.SQL*Plus Copy 命令通过SQL*Net在 ...
- Eclipse配置Maven详细教程
一.使用eclipse自带的maven插件 首先,现在下载Eclipse Mars之后的版本,基本上都自带了maven插件,无需自己再安装maven. 有几个注意点: 1.默认的本地仓库的目录是在C: ...