一. iter&yield迭代器

    1.1 iter

 names = iter(['zeng', 'chun', 'yun'])
print(names)
print(names.__next__())
print(names.__next__())
print(names.__next__())
print(names.__next__()) #第一个输出打印迭代器对象
#第二三四次next方法每次都去获取迭代对象的值,每次往下取一个值,直到取完
#第五次输出 print(names.__next__())
#StopIteration,因为迭代器里面的对象已经取完了,所以出现这个异常

  1.2 yield

 def fei(num):
x, y, z = 0, 0, 1
while x < num:
if x == 0: # 当第一次循环时,返回数列0
yield y # 生成器返回一个迭代器对象
else: # 否则返回z
yield z
y, z = z, y + z
x += 1 print(fei(9).__next__()) # 只从迭代器里面取一次值
# fei(9).__next__()
for i in fei(9): # 通过遍历获取迭代器内容
print(i)

   1.3  生成器的异步应用

import time

def consumer(name):  # 定义消费者函数
print("%s 准备吃包子啦!" % name) # 打印消费者名字
while True:
baozi = yield # 当代码运行到这时,返回一个迭代器对象,当对象第二次调用时,会接收值并赋值给baozi
print("包子[%s]来了,被[%s]吃了!" % (baozi, name)) # 打印当前使用的迭代器对象,及接收的值 def producer(*name): # 定义一个生产者函数,并使用动态参数
if len(name) == 3: # 当传入三个参数时,调用三次消费者函数方法
c = consumer(name[0])
c2 = consumer(name[1])
c3 = consumer(name[2])
c.__next__() # 通过函数内置方法获取迭代器内部元素
c2.__next__()
c3.__next__()
print("老子开始准备做包子啦!")
for i in range(1, 11):
time.sleep(1)
print("做了%s个包子!" % len(name))
c.send(i) # 通过迭代器方法的send属性给生成器传送值
c2.send(i)
c3.send(i) producer("alex", 'zengchunyun', 'peiqi') # 创建一个生产者对象,并传入三个消费者名字

  二. 装饰器

    2.1 首先了解一下函数

def func():
print('hello') print(func) # 第一次输出的是一个函数对象
print(type(func)) #第二次输出的是一个类型为函数
func() # 第三次才是执行这个函数
print(func()) #第四次则是执行函数后,并打印函数的返回结果,函数没有指定返回内容,所以使用默认返回值,None
print(type(func())) # 第五次也是先执行函数,然后打印返回值对象的类型,所以可以看出,返回值对象类型是NoneType # 第一次
#<function func at 0x100756f28>
# 第二次
#<class 'function'>
# 第三次
#hello
# 第四次
#hello
#None
# 第五次
#hello
#<class 'NoneType'>

    通过上述总结一句话,函数不加括号是没有执行的,这时的这个函数名只是一个函数对象,而加括号后,函数将会执行函数体代码,

  最终这个函数则是函数执行完后的返回的对象

    2.2 装饰器

    有了上面这个基础后,我们再来看看装饰器

 def wrapper(func):
print(func) # 打印参数
return func # 返回参数 @wrapper # 使用装饰器
def index():
print('welcome') index() # 执行顺序是,解释器从上往下读取代码
# 遇到函数时,只加载定义的函数对象,并不执行函数体代码
# 然后遇到装饰器@wrapper时
# 解释器会跳到这个wrapper函数
# 然后执行这个wrapper函数内部代码
# 我们通过观察得知,这个wrapper函数一定会传入一个参数,因为测试发现,不传入一个参数,程序执行会抛出需要一个参数的异常错误.
# 通过分析这个参数,发现这个参数打印结果是一个函数对象
# 然后wrapper函数体代码执行完毕后,继续往下执行,遇到函数index,
# 也是只是加载这个函数对象,并不执行内部函数体代码
# 当遇到代码index()时,结合到我们之前积累的函数基础知识,
# 这个写法实际是开始执行一个函数,所以解释器会跳到指定的index函数对象
# 然后开始执行这个函数体代码块,
# 整个执行过程就结束了 # 以下为代码执行结果
# <function index at 0x1010ed0d0>
# welcome

    可能你对上面这个过程还是不够了解装饰器,那么我们再通过下面这个例子说明装饰器的工作原理

 def wrapper(func):
print(func) # 打印参数
# return func # 返回参数 ,现在注释掉这个返回值 @wrapper # 使用装饰器
def index():
print('welcome') print(type(index)) # 加上一句输出类型代码的语句
index() #我们在上面这个例子中,把函数wrapper中的返回值给注释掉了,代码执行结果 # function index at 0x1011ed0d0>
# <class 'NoneType'>
# Traceback (most recent call last):
# File "/Users/zengchunyun/PycharmProjects/s12/day4/noteext.py", line 68, in <module>
# index()
# TypeError: 'NoneType' object is not callable # 首先我们来分析一下这个结果
# 你会不会很惊讶?我们只是针对第一个例子的代码仅仅只是注释掉一个返回值而已,代码就不能工作了 # 首先解释器还是从上往下读取代码
# 遇到函数时,只加载定义的函数对象,并不执行函数体代码
# 然后遇到装饰器@wrapper时
# 解释器会跳到这个wrapper函数
# 然后执行这个wrapper函数内部代码
# 通过分析这个参数,发现这个参数打印结果是一个函数对象
# 然后wrapper函数体代码执行完毕后,继续往下执行,遇到函数index,
# 也是只是加载这个函数对象,并不执行内部函数体代码
# 关键点来了
# 代码执行到打印对象类型的语句时,结果却是一个NoneType的类型,根据我们之前对函数的基本介绍,这里的类型应该是一个函数类型才对啊
# 怎么回事呢?我们明明定义了index函数,怎么打印的类型却是NoneType类型?
# 我们之前也看到只有函数没有返回值时,函数默认会返回一个None对象,故而这个对象的类型也就是NoneType类型了,
# 我们仅仅只是加了一个装饰器代码@wrapper,其他都没有变,为什么会出现这个情况呢
# 我们上一个例子已经说明,这个装饰器会携带一个参数,这个参数为一个函数对象,
# 实际上,这个时候这个装饰器会对引用装饰器的函数,也就是我们这里的index函数进行重构,
# 所以如果我们如果不返回一个函数对象时,那么这个时候的index实质是一个普通的对象,不是函数类型了
# 它已经被赋予None这个值了,而None不是一个函数对象,所以就没有调用方法,就不能以括号方式执行
# 这时解释器读到index()这句代码,大家依据之前的理念,都能看出这个是去执行index这个函数内部代码块的语句
# 但是这个时候,解释器却在这个时候抛出异常了
# 返回类型错误,TypeError: 'NoneType' object is not callable
# 这个错误说我们的index执行后,是不能被调用的,只有对象类型为函数才有内置调用方法
# 因为这个index已经被重构,返回值已经变成了None,也就是说,index 对象目前仅仅是一个普通标识符,不是函数

    2.3 装饰器的高级应用

      我们通过上面的事咧可知,只要代码执行到装饰器标识符,都会去执行装饰器函数体,但是这个不是我们想要的,我们希望的是

    只有我们调用引用装饰器的函数时,才去执行这个装饰器函数体,那怎么办呢?我们知道,只有类型是函数对象时,代码是不会被执行,

    只是加载到内存而已,那好吧,我们直接返回一个函数对象不就好了?

      我们来看看代码实现

 def wrapper(func):
def inner():
print(func) # 输出是一个函数对象
func() # 这里实际是执行我们这个例子中原先定义的index函数对象的函数体
return inner
# print(func) # 打印参数
# return func # 返回参数 ,现在注释掉这个返回值 @wrapper # 使用装饰器
def index():
print('welcome') print(type(index)) # 加上一句输出类型代码的语句
index() # 首先看看这种情况
# 代码执行到index()时,啥也没有,我们明明打印了一句welcome,为什么没有输出信息,这也就再次证明了,
# 实质是这个index已经等价于装饰器的inner这个函数了,因为装饰器返回的是inner这个函数对象
# 我们既想用装饰器,又想执行调用装饰器的内部代码时怎么办呢?
# 我们已经知道,装饰器会携带一个参数,这个参数是引用装饰器对象的一个函数对象
# 既然是一个函数对象,那我们是不是可以直接执行这个函数对象呢?
# 答案是肯定的,所以我们直接在这个装饰器里执行这个函数对象,等于就是执行我们原先那个函数的函数体
# 这个例子就满足了我们的需求,当我们不调用index函数时,得到的仅仅是一个函数对象,并不会执行函数体代码

  有参数的函数,或装饰器实现传参实例

 # 无参装饰器,有参函数
def wrapper(func):
def inner(name): # 这个参数最终会传给这个函数体内部需要调用参数的对象
func(name) # 这个参数个数是由原来的函数,也就是我们这里的index函数决定参数个数的
return inner @wrapper # 使用装饰器
def index(name): # 传入一个参数
print('welcome %s' % name) index('zengchunyun')

无参装饰器,有参函数

 # 无参装饰器,多参函数
def wrapper(func):
def inner(*args): # 使用动态参数
func(*args)
return inner @wrapper # 使用装饰器
def index(*args): # 传入一个参数
print('welcome %s' % ' '.join(args)) index('zengchunyun', 'goodbye')

无参装饰器,多参函数

 # 无参装饰器,多参函数2
def wrapper(func):
def inner(*args, **kwargs): # 使用动态参数
func(*args, **kwargs)
return inner @wrapper # 使用装饰器
def index(*args, **kwargs): # 传入一个参数
print('welcome %s' % ' '.join(args)) index('zengchunyun', 'goodbye')

无参装饰器,多参函数2

 # 有参装饰器,多参函数
def one():
print('one') def two():
print('two') def func(arg1, arg2):
def wrapper(oldfunc):
def inner(*args, **kwargs): # 使用动态参数
arg1()
arg2()
oldfunc(*args, **kwargs)
return inner
return wrapper @func(one, two) # 使用装饰器
def index(*args, **kwargs): # 传入一个参数
print('welcome %s' % ' '.join(args)) index('zengchunyun', 'goodbye') # 解释器遇到装饰器,由于这个装饰器是一个可执行函数
# 故而先执行函数,再次就成了我们所认知的普通装饰器了

# 有参装饰器,多参函数

python进阶学习三——第四天的更多相关文章

  1. python进阶学习笔记(四)--多线程thread

    在使用多线程之前,我们首页要理解什么是进程和线程. 什么是进程? 计算机程序只不过是磁盘中可执行的,二进制(或其它类型)的数据.它们只有在被读取到内存中,被操作系统调用的时候才开始它们的生命期.进程( ...

  2. Python进阶学习之特殊方法实例详析

    Python进阶学习之特殊方法实例详析 最近在学习python,学习到了一个之前没接触过的--特殊方法. 什么是特殊方法?当我们在设计一个类的时候,python中有一个用于初始化的方法$__init_ ...

  3. Python基础学习三

    Python基础学习三 1.列表与元组 len()函数:可以获取列表的元素个数. append()函数:用于在列表的最后添加元素. sort()函数:用于排序元素 insert()函数:用于在指定位置 ...

  4. python进阶学习笔记(一)

    python进阶部分要学习的内容: 学习目标: 1.函数式编程 1.1,什么是函数式编程 函数式编程是一种抽象计算的编程模式 不同语言的抽象层次不同: 函数式编程的特点: python支持的函数式编程 ...

  5. 魔法方法推开Python进阶学习大门

    热爱Python Python是Guido van Rossum设计出来的让使用者觉得如沐春风的一门编程语言.2020年11月12日,64岁的Python之父宣布由于退休生活太无聊,自己决定加入Mic ...

  6. python进阶学习(四)

    在使用多线程之前,我们首页要理解什么是进程和线程. 什么是进程? 计算机程序只不过是磁盘中可执行的,二进制(或其它类型)的数据.它们只有在被读取到内存中,被操作系统调用的时候才开始它们的生命期.进程( ...

  7. python进阶学习(三)

    本节通过SQLite了解数据库操作 ------------------------- 数据库支持 使用简单的纯文本只能实现有退限的功能,所需要引入数据库,完成更强大的功能,本节使用的简单数据库SQL ...

  8. python进阶学习笔记(三)

    3.类的继承 3.1,python中什么是类的继承 答案是肯定的. 也就是说,如果一个实例是一个子类,那么它也是一个父类 总是从某各类继承,如果没有合适的类,就要从object类继承:super(). ...

  9. Python进阶 学习笔记(三)

    (涉及内容:定制类) __str__和__repr__ 如果要把一个类的实例变成 str,就需要实现特殊方法__str__(): class Person(object): def __init__( ...

随机推荐

  1. JavaScript 简介

    JavaScript是一种专为网页交互而设计的脚本语言,由下列三个不同的部分组成: ECMAScript,由ECMA-262 定义,提供核心语言功能: DOM, 提供访问和操作网页内容的方法和接口; ...

  2. JNI数据类型(转)

    本文原创,转载请注明出处:http://blog.csdn.net/qinjuning 在Java存在两种数据类型: 基本类型 和 引用类型 ,大家都懂的 . 在JNI的世界里也存在类似的数据类型,与 ...

  3. 总结列表显示ListView知识点

    全选ListView的item条目 单选ListView的条目 多选ListView的item条目 自定义ArrayAdapter动态改变ListView的不同item样式 动态增加和删除ListVi ...

  4. windows OBJECT查找

    PspCidTable表里.索引值总之4的倍数.也就是说 PID/4 才是PspCidTable索引.*8 才是PsPCidTable+偏移.获取进程对应的 _HANDLE_TABLE_ENTRY 结 ...

  5. 使用while代替for循环的几个习题

    1:兔子问题 2:100以内质数的和 3:单位给发了一张150元购物卡,拿着到超市买三类洗化用品.洗发水15元,香皂2元,牙刷5元.求刚好花完150元,有多少种买法,没种买法都是各买几样? 总结:wh ...

  6. 友盟页面统计 - 关于Viewpager中的Fragment的生命周期

    Activity和Fragment各自理论上的生命周期 Activity的生命周期是较为经典也最清晰的,在此不表: Fragment从出现到广泛运用也有一段时间了,其标准生命周期也仅比Activity ...

  7. 计数排序-java

    今天看了一本书,书里有道题,题目很常见,排序,明了点说: 需求:输入:最多有n个正整数,每个数都小于n, n为107 ,没有重复的整数 输出:按升序排列 思路:假设有一组集合 {1,3,5,6,11, ...

  8. 分数try catch

    要求:编写一个程序,此程序在运行时要求用户输入一个 整数,代表某门课的考试成绩,程序接着给出“不及格”.“及格”.“中”.“良”.“优”的结论.要求程序必须具备足够的健壮性,不管用户输入什 么样的内容 ...

  9. Bestcoder round #65 && hdu 5592 ZYB's Premutation 线段树

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submissio ...

  10. 原生 js 模拟 alert 弹窗

    复制头部的 js 代码到你的 js 文件的任何地方,调用Chef.alert方法传入相应的参数即可并没有什么功能,只是一个提示的作用,可能样式比 alert 的弹窗好看点,css是写在js里的,只要你 ...