一、装饰器

  1.1 闭包函数用法

# 需求:
# 执行一个函数前需要认证是否登录,如果登录则不需再登录.
# 只认证一次,后续操作无需认证
# 要求认证使用闭包函数用法
# 闭包函数 = 函数嵌套 + 命名空间作用域 + 函数对象
login_status = {
'user':None,
'status':None
} def login(user:str,pwd:str):
if user == 'jmz' and pwd =='':
return True
else:
return False # 认证用户是否登录成功
def auth(func):
def wrapper(*args,**kwargs):
if login_status['user'] and login_status['status']:
return func(*args,**kwargs)
else:
uname = input('username>>').strip()
upwd = input('password>>').strip()
res =login(uname,upwd)
if res:
return func(*args, **kwargs)
else:
print('认证失败')
return wrapper def index():
print('from index') index = auth(index) def cat():
print('form cat') index()
cat()

实现

  1.2 什么是装饰器

#  什么是装饰器
# 1、装饰即修饰,器指的就是工具
# 2、装饰器本身可以是任意可调用的对象
# 3、被装饰的对象也可以是任意可调用的对象

  1.3 为什么要使用装饰器

#  为什么要使用装饰器
# 1、在不改变原有的调用方式,不改变原方法的前提下,如何实现对内容上的新增??
# 例如:
# 今天公司cto要求对一些方法添加文件的日志记录(此时你是否需要对每一个方法添加日志的记录?)
# 第二天CTO 突然改变主意说 原来的方法添加日志记录改为 mysql 记录(此时你是否又要修改每一个方法的日志记录??)
# 我知道你此时此刻一定会想,我可以写一个日志记录方法,让每一个方法内部调用这个方法(很不错的想法)
# 第三天 你的公司cto 告诉你,我的日志一定要记录那些方法执行的开始和结束时间。(是不是有点懵X了?你该怎么办??)

  1.4 怎么用装饰器

    # 是否是和上面的那个闭包函数很像呀(其实装饰器就是闭包函数的一种运用)
# 装饰器语法糖:
# 在被装饰对象的正上方一行写@装饰器的名字
# @auth ==> func = auth(func)
login_status = {
'user':None,
'status':None
} def login(user:str,pwd:str):
if user == 'jmz' and pwd =='':
login_status['user']=user
login_status['status']=True
return True
else:
return False # 认证用户是否登录成功
def auth(func):
def wrapper(*args,**kwargs):
if login_status['user'] and login_status['status']:
return func(*args,**kwargs)
else:
uname = input('username>>').strip()
upwd = input('password>>').strip()
res =login(uname,upwd)
if res:
return func(*args, **kwargs)
else:
print('认证失败')
return wrapper @auth
def index():
print('from index') @auth
def cat():
print('form cat') index()
cat()

怎么使用装饰器

  1.5 有参装饰器

    # 上面的装饰器只是使用了固定的用户jmz,登录,而且没有实现以哪种方式 验证(文件方式,还是mysql方式)
# 如果我需要暂时以文件的方式验证,后期再改为使用mysql 方式验证该如何使用??? (尽量减少代码的修改)
# 要求:
# 1、验证的方式是不固定的
# 2、使用的装饰器要兼顾至少两种以上的验证方式
# 3、需要能够随时给方法添加验证或撤销验证
login_status = {
'user':None,
'status':None
} def login(user:str,pwd:str,type='file'):
if type == 'file':
# 假设这就是文件认证
if user == 'jmz' and pwd == '':
login_status['user'] = user
login_status['status'] = True
return True
else:
return False
elif type =='mysql':
# 假设这就是mysql认证
if user == 'jmz' and pwd == '':
login_status['user'] = user
login_status['status'] = True
return True
else:
return False # 认证用户是否登录成功
def auth(type='file'):
def auth2(func):
def wrapper(*args,**kwargs):
if login_status['user'] and login_status['status']:
return func(*args,**kwargs)
else:
uname = input('username>>').strip()
upwd = input('password>>').strip()
res =login(uname,upwd,type)
if res:
return func(*args, **kwargs)
else:
print('认证失败')
return wrapper
return auth2 @auth('file')
def index():
print('from index') @auth('file')
def cat():
print('form cat') index()
cat()

有参装饰器

二、迭代器

  2.1 什么是迭代器?

    迭代的工具:

      迭代是一个重复的过程,每一次的重复都是基于上一次的结果进行的      

# 这不是迭代
while True:
print('....')

  2.2 为什么要使用迭代器?

    找到一种不依赖于索引的迭代的方式?

# 1、列表是自带索引的,那么如何迭代没有索引的呢???(禁止使用for)
l = ['a','b','c']
k = 0
while k<len(l):
print(l[k])
k+=1 # 2、如何循环取一个无限大的值?
# 如果使用上面的方法显然是不现实的,因为你的列表是存不下无限大的值的(列表的数据占着内存的空间) # 那怎么办呢?

  2.3 怎么使用迭代器?

    2.3.1 可迭代对象

        python 中,但凡内置__iter__方法的,都是可迭代对象

a = 1
b = 1.1
# 以下都是可以使用__iter__ 方法
c = 'abcd'
#c.__iter__()
d = ['a','b','c']
# d.__iter__()
e = ('a','b','c')
# e.__iter__()
f = {'a':1,'b':2}
# f.__iter__()
g={'a','b','c'}
# g.__iter__()
h=open('a.txt','r') # 本身就是一个迭代器对象

     2.3.2 迭代器对象       

#     可迭代对象:在python中但凡有内置方法__iter__的对象,都是可迭代对象
# 迭代器对象 :
# 执行可迭代对象下__iter__方法后得到迭代器对象
# 迭代器对象的内置方法
# __next__
# __iter__方法,执行该方法得到仍然是迭代器本身,干什么用??(等下解释) # 有了迭代器我们就不需要依赖索引取值了
#       注意: 
#      1、迭代器对象一定是对迭代对象
#      2、可迭代对象不一定是迭代器对象
 
dic = {'a':1,'b':2,'c':3,'d':4}
iter_obj = dic.__iter__()
print(next(iter_obj)) # a
print(next(iter_obj)) # b iter_obj1 = dic.__iter__() # 重新 做了一次迭代器对象操作
print(next(iter_obj1)) # a。 iter_obj = iter_obj.__iter__() # iter_obj.__iter__() is iter_obj #True
#iter_obj.__iter__() 无论执行多少次都是本身
print(next(iter_obj)) # c # 会继续给予上一次的操作继续执行
print(next(iter_obj)) # d

__iter__ ,迭代器对象执行后任然是本身

#for循环的底层运行机制:for循环可以称之为迭代器循环
#1、先调用in后那个对象的__iter__方法,得到该对象的迭代器对象
#2、执行迭代器对象的__next__方法,将得到的返回值赋值in前面的变量名,然后执行一次循环体代码
#3、循环往复,直到取干净迭代器内所有的值,自动捕捉异常结束循环
dic = {'a':1,'b':2} iter_obj = dic.__iter__()
while True:
try :
print(dic[iter_obj.__next__()])
except StopIteration:
break for k in dic: #iter_obj=dic.__iter__()
print(dic[k])

for 循环实现原理

   2.4 总结

# 优点:
# 1、不依赖于索引的迭代取值
# 2、节省内存,计算取值 # 缺点:
# 1、无法获取长度
# 2、只能next,不能向上取值,只能想下直至结束

迭代器的优缺点

三、生成器

  3.1 什么是生成器 

# 函数内部含有yield关键字,那么该函数() 即为生成器。
# 自定义迭代器 def func():
print('first')
yield 1
print('second')
yield 2
print('third')
yield 3 f = func()
print(f) #<generator object func at 0x0000000001DF0DB0>

  3.2 生成器的使用方式

# yield 返回值操作
# 生成器就是迭代器,所以用法与迭代器一样 # 仿range函数
def range(start:int,end:int,step=1):
while start < end:
yield start # 当一次next 执行到这里时便会返回start,并停止,下一次操作会从本次停止的地方继续往下执行,
start += step # 直到再次遇到 yield 再停止,返回后面的值 num = range(1,6,2)
print(num.__next__())
print(num.__next__())
print(num.__next__()) # yield : 具有停止本次操作,并return yield 后面的值,与return的返回值一样

生成器使用方式一

# yield 传值操作
def doing(name):
print('%s开始干活了'%name)
thing_list = set()
while True:
do_thing = yield thing_list # 返回thing_list
print('%s 正在%s'%(name,do_thing))
thing_list.add(do_thing) xiaoming = doing('xiaoming')
next(xiaoming) # 第一次使用,需暂停到yield 那边
print(xiaoming.send('做饭')) # 先给yield 传值, 之后再接受执行到下一个yield的返回值
print(xiaoming.send('吃饭'))
print(xiaoming.send('干活'))
print(xiaoming.send('睡觉'))
xiaoming.close() # 关闭生成器
xiaoming.send('起床时') # 此时无法再传值执行,并且报错

生成器使用方式二

  3.3 总结

# 1、可以像return 一样,返回值,但又可以多次返回
# 2、可以挂起/保存函数的当前状态,可以达到随用随启动的程度
# 3、可以多次传值操作

四、练习

# 作业一:写一个取基数的操作 (迭代器)
# 作业二:咖啡3元,糖0.5元 牛奶2元,平时咖啡单点的,活动需要,需加糖与牛奶捆绑销售(装饰器)
# 作业三:用户购买商品,以邮箱或短信的形式通知(装饰器)
#作业一
def jishu():
num = 1
while True:
is_true = True
if num > 1:
count = 2
while count < num - 1:
if num%count==0:
is_true = False
break
count +=1
if is_true:
yield num
num +=1 num = jishu()
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num)) #作业二
def sugar(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
res += 0.5
return res
return wrapper def milk(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
res += 2.5
return res
return wrapper @sugar
@milk
def coffee():
return 3 print(coffee()) #作业三
def notice(type='email'):
def shopping(func):
def wrapper(*args,**kwargs):
if type == 'email':
print('邮箱通知成功')
elif type == 'sms':
print('短信通知成功')
return func(*args,**kwargs)
return wrapper
return shopping @notice('sms')
def shopping(good):
print('成功购买了%s商品'%good) shopping('电脑')

作业

五年级--python函数高级运用的更多相关文章

  1. [Python学习笔记][第五章Python函数设计与使用]

    2016/1/29学习内容 第四章 Python函数设计与使用 之前的几页忘记保存了 很伤心 变量作用域 -一个变量已在函数外定义,如果在函数内需要修改这个变量的值,并将这个赋值结果反映到函数之外,可 ...

  2. python高级(五)—— python函数(一等对象)

    本文主要内容 一等对象 普通函数 & 高阶函数 可调用对象 & 自定义可调用类型 函数内省 函数注释 python高级——目录 文中代码均放在github上:https://githu ...

  3. python函数高级特性

    掌握了Python的数据类型.语句.函数,基本可以编写出很多有用的程序了.但是Python中,代码不是越多越好,而是越少越好.代码不是越复杂越好,而是越简单越好.基于这一思想,我们来介绍python中 ...

  4. 四年级--python函数基础用法

    一.函数的定义,调用和返回值 1.1 语法 def 函数(参数一,参数二...): ''' 文档注释 ''' 代码逻辑一 代码逻辑二 .... return 返回值 1.2 定义函数的三种形式 说明: ...

  5. Python —— 函数高级特性(切片、迭代、列表生成式、生成器、迭代器)

    一.切片(Slice) 在很多编程语言中,针对字符串提供了很多截取函数(i.e.  substring),目的就是对字符串切片.python中没有针对字符串的截取函数,需要通过“切片”来完成. 取一个 ...

  6. 12、Python函数高级(命名空间、作用域、装饰器)

    一.名称空间和作用域 1.命名空间(Namespace) 命名空间是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的. 命名空间提供了在项目中避免名字冲突的一种方法.各个命名空 ...

  7. Python函数高级

    函数对象 在面向对象编程中 一切皆对象 函数在python中是第一类对象 函数可以这么用 可以被引用 def func(): print('hello world !') ​ f=func f() 可 ...

  8. python3笔记十五:python函数

    一:学习内容 函数概述 函数的参数与返回值 参数值传递和引用传递 关键字参数 默认参数 不定长参数 二:函数概述 1.本质:函数就是对功能的封装 2.优点: 简化代码结构,增加了代码的复用度(重复使用 ...

  9. (五)、python 函数

    一.函数 def 函数名(参数): ... 函数体 ... 返回值 函数的定义主要有如下要点: def:表示函数的关键字 函数名:函数的名称,日后根据函数名调用函数 函数体:函数中进行一系列的逻辑计算 ...

随机推荐

  1. 【翻译】Ext JS 6早期访问版本发布

    早期访问版本是什么 如何参与 都包括什么 Sencha Ext JS 6 Sencha Pivot Grid Sencha Cmd 6 JetBrains IDE插件 反馈 原文:Announcing ...

  2. Socket编程实践(11) --epoll原理与封装

    常用模型的特点 Linux 下设计并发网络程序,有典型的Apache模型(Process Per Connection,PPC), TPC(Thread Per Connection)模型,以及 se ...

  3. Scipy教程 - 距离计算库scipy.spatial.distance

    http://blog.csdn.net/pipisorry/article/details/48814183 在scipy.spatial中最重要的模块应该就是距离计算模块distance了. fr ...

  4. Java模式之模板方法模式

    当我们遇到的业务逻辑具有大致相同的方式的时候,我们也许就该将这个业务逻辑抽象出来,采用模板方法,来进行封装我们的代码,提高代码的重用性,以及可维护性.下面是我的一个复习用的案例: 第一步:我们需要一个 ...

  5. log4j的一些配置

    a). 新建Java Project>>新建package>>新建java类: b). import jar包(一个就够),这里我用的是log4j-1.2.14.jar, c) ...

  6. 网站开发进阶(三十一)js如何将html表格导出为excel文件(后记)

    js如何将html表格导出为excel文件(后记) 前言 项目前期做了个导出Excel表格的功能,但是经过测试发现只有在IE上才可以正确实现,在Chrome等浏览器中无法实现导出效果.经过上网搜索,尝 ...

  7. 使用GDAL将下载的Google卫星图像转为带坐标的tif

    网上有很多下载Google地图的卫片的软件,一般下载下来的图像都是jpg格式的,另外附带一个坐标信息的描述文件.这样的数据不能直接拿来在遥感或者GIS软件中使用,因为图像里面没有投影和坐标信息,所以就 ...

  8. Android群英传笔记——第七章:Android动画机制和使用技巧

    Android群英传笔记--第七章:Android动画机制和使用技巧 想来,最 近忙的不可开交,都把看书给冷落了,还有好几本没有看完呢,速度得加快了 今天看了第七章,Android动画效果一直是人家中 ...

  9. OSB开发常用资料

    成功搭建OSB环境并运行HelloWorld项目 http://www.beansoft.biz/?p=2066 Oracle Service Bus 11gR1开发环境安装文档 http://www ...

  10. DBUtils源码分析

    其实,在这篇文章里,我只是分析了dbutis的query的运作流程. 至于类为什么要这样设计,蕴含的设计模式等等高级知识点咱们在下节再探讨. 先看看最简单的DBUtils是如何工作的. 数据库里有一张 ...