[Python][华为云Python编程创造营][学习笔记][12_Python三大神器]

网友投稿 537 2022-05-30

1,迭代器

1.1,迭代

1.1.1,迭代是Python中用于访问序列结构数据的一种方式

- 当我们用一个循环(比如for循环)来遍历容器(比如列表、元组)中的元素时,这种遍历的过程就叫迭代。

1.2,可迭代对象

1.2.1,可以被for循环遍历的对象成为可迭代对象

- 可迭代对象中需要实现__iter__或者__getitem__方法

1.3,迭代器

1.3.1,迭代器是指遵循迭代器协议(iterator protocol)的对象

- 迭代器协议:实现对象的__iter__和__next__方法,其中__iter__方法返回迭代器对象本身,next()方法返回容器的下一个元素,在没有后续元素时抛出StopIteration异常。

- 可迭代对象不是迭代器。

- 使用iter()获取迭代器对象。

1.3.2,迭代器是一个可以记住遍历的位置的对象

- 迭代器对象从集合的第一个元素开始访问(next),直到所有的元素被访问结束。迭代器只能往前不能后退。

1.3.3,对于迭代器对象,可以使用next方法获取

- 当元素迭代完后会出现StopIteration异常。

# 字符串,列表或者元组对象都可用于创建迭代器 list = [1,2,3,4] it = iter(list) # 创建迭代器对象 print(next(it)) # 输出迭代器的下一个元素 1 print(next(it)) # 输出迭代器的下一个元素 2 # 迭代器对象可以使用常规for语句进行遍历 list = [1,2,3,4] it = iter(list) # 创建迭代器对象 for x in it: print(x,end=" ") # 1 2 3 4 # 也可以使用next()函数 import sys # 引入sys模块 list = [1,2,3,4] it = iter(list) # 创建迭代器对象 while True: try: print(next(it),end=" ") # 1 2 3 4 except StopIteration: sys.exit() # 创建一个返回数字的迭代器,初始值为1,逐步递增2 class MyNumber: def __iter__(self): self.a = 1 return self def __next__(self): x = self.a self.a += 2 return x myclass = MyNumber() myiter=iter(myclass) print(next(myiter)) # 1 print(next(myiter)) # 3 print(next(myiter)) # 5 print(next(myiter)) # 7 print(next(myiter)) # 9 # 迭代20次后停止执行 class MyNumbers: def __iter__(self): self.a = 1 return self def __next__(self): if self.a <= 10: x = self.a self.a += 1 return x else: raise StopIteration myclass = MyNumbers() myiter = iter(myclass) for x in myiter: print(x,end=" ") # 1 2 3 4 5 6 7 8 9 10

2,生成器

2.1,生成器(generator)是一类特殊的迭代器

2.1.1,生成器每次在迭代时可以返回一个或多个值,它可以记录当前状态

- 生成器的创建方式:使用yield关键字,使用生成器表达式(推导式)。

2.2,生成器推导式

2.2.1,推导式形式

G = (x*2 for x in range(5)) print(type(G)) #

2.2.2,判断是否是生成器

from collections.abc import Generator G = (x*2 for x in range(5)) res = isinstance(G,Generator) print(res) # True

[Python][华为云Python编程创造营][学习笔记][12_Python三大神器]

2.3,yield创建生成器

2.3.1,使用yield创建生成器

- 通过yield创建一个产生斐波那契数列的生成器

import sys def fibonacci(n): # 生成器函数 - 斐波那契数列 a, b, counter = 0, 1, 0 while True: if (counter > n): return yield a a, b = b, a+b counter += 1 f = fibonacci(10) # f是一个迭代器,由生成器返回生成 while True: try: print(next(f),end=" ") # 0 1 1 2 3 5 8 13 21 34 55 except StopIteration: sys.exit()

2.3.2,为了更好了解yield的工作流程,我们通过Debug来观察

2.4,生成器取值

2.4.1,生成器可以使用next和send取值

- next,获取下一个元素。

- send,获取下一个元素,同时可以向生成器中传递一个值。

- next等同于send(None)。

- 第一次取值时,需要使用next或者send(None)。

2.5,执行过程(1)

2.5.1,下面例子的执行过程

def fib(n): current = 0 num1, num2 = 0, 1 while current < n: num = num1 # 1 num1, num2 = num2, num1+num2 # 2 current += 1 yield num # 3 return 'done' # 6 g = fib(5) # 4 next(g) # 5 # 执行过程:-4 -1 -2 -3 -5 -1 -2 ... -6

2.6,执行过程(2)

2.6.1,使用yield声明函数为生成器

2.6.2,当程序执行到yield处时,生成器函数暂停,等待下一次唤醒(next,send)

- 并且返回当前值。

- 和return相似,但是程序暂停而不是结束。

2.7,关系

3,装饰器

装饰器(Decorators)是修改其他函数功能的函数。

3.1,闭包(1)

3.1.1,闭包:是由函数及其相关的引用环境组合而成的实体。

3.1.2,不同编程语言实现闭包的方式是不同的,Python中闭包从表现形式上看,如果在一个内部函数里,对在外部作用域(不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包。

def func(x): def inner(y): return x+y return inner

3.2,闭包(2)

3.2.1,闭包中不可以直接修改外部函数的局部变量

- 类似于不能直接在函数中修改全局变量(可变类型除外),需要使用关键字nonlocal。

3.2.2,闭包的作用

- 当闭包执行完后,仍然能够保持住当前的运行环境。

- 闭包可以根据外部作用域的局部变量来得到不同的结果。

def func1(func): def inner(): print("func1") func() return inner def func2(): print("func2") func1(func2)()

3.3,装饰器(1)

3.3.1,装饰器本质上是一个Python函数,可以在不改变代码结构的情况下给代码添加新的功能。

3.3.2,装饰器的工作过程:将被装饰的函数当作参数传递给装饰器函数(名称相同的函数),并返回装饰后被装饰的函数。

3.3.3,装饰器是闭包的一种应用。

3.3.4,装饰器的使用

# @装饰器函数 # def func(): # pass

3.4,装饰器(2)

3.4.1,装饰器的作用

def light(func): # 装饰器函数 print("获得神光棒x1") def tiga(): func() print("我是光之巨人") return tiga() @light def person(): print("我是某胜利队队员大骨") person() # 输出结果 # 获得神光棒x1 # 我是某胜利队队员大骨 # 我是光之巨人 # TypeError: 'NoneType' object is not callable def light(func): # 装饰器函数 print("获得神光棒x1") def tiga(): func() print("我是光之巨人") return tiga def person(): print("我是某胜利队队员大骨") light(person)() # 输出结果 # 获得神光棒x1 # 我是某胜利队队员大骨 # 我是光之巨人

3.5,丢失的信息

3.5.1,装饰器不会改变原有函数代码,但是会丢失一部分信息

- 被装饰函数的元信息会丢失,如:名字、文档字符串、注解和参数签名

def light(func): # 装饰器函数 print("获得神光棒x1") def tiga(): func() print("我是光之巨人") return tiga @light def person(): # 被装饰的函数 '''我要打怪兽''' print("我是某胜利队队员大骨") person() help(person) # 输出结果 # 获得神光棒x1 # 我是某胜利队队员大骨 # 我是光之巨人 # Help on function tiga in module __main__: # tiga()

3.6,wraps

3.6.1,为了保留因为使用装饰器而丢失的信息,可以使用Python中本身提供的装饰器@wraps来解决

from functools import wraps def light(func): print("获得神光棒x1") @wraps(func) def tiga(): func() print("我是光之巨人") return tiga @light def person(): '''我想打怪兽''' print("我是某胜利队队员大骨") person() help(person) # 输出结果 # 获得神光棒x1 # 我是某胜利队队员大骨 # 我是光之巨人 # Help on function person in module __main__: # person() # 我想打怪兽

3.7,被装饰函数的参数

3.7.1,当被装饰函数拥有参数时,如何在装饰器过程中进行传递?如何构建一个通用的装饰器?

from functools import wraps def func1(func): @wraps(func) def inner(a, b): print("func1") func(a, b) return inner @func1 def func2(a, b): print(a+b) func2(1, 2) # 输出结果 # func1 # 3

3.8,带有参数的装饰器

3.8.1,如何通过装饰器的参数来控制装饰器?

- 对当前用户增加权限:VIP,SVIP,VIP中P

def Decorator(name=None,level="普通会员"): def outer(func): def inner(name): print("欢迎登陆, %s"%level) func(name) return inner return outer @Decorator(level="SVIP") def func(name): print(name) func("张三") # 输出结果 # 欢迎登陆, SVIP # 张三

- 通过外部参数,返回一个装饰器

3.9,装饰器与类(1)

3.9.1,装饰器不仅可以是函数,还可以是类(如property)

- 同样,装饰器不仅可以修饰函数,还可以修饰类

3.9.2,装饰器装饰类

def singleton(cls,*args,**kw): instance={} def _singleton(): if cls not in instance: instance[cls]=cls(*args,**kw) return instance[cls] return _singleton @singleton class Singleton(object): def __init__(self): self.num_sum=0 def add(self): self.num_sum=100

4.0,装饰器与类(2)

4.0.1,将装饰器定义为类的形式。

- __call__:魔法方法,可以让类像方法一样被调用。

import time class Wrapper(): def __init__(self,func): self.func=func def __call__(self,*args,**kwargs): start=time.time() result=self.func(*args,**kwargs) end=time.time() print(end-start) return result @Wrapper def func(num): time.sleep(3) return num func(1) # 3.000171422958374

4.1,多个装饰器

def Tiga(func): print("给我力量吧,Tiga") def tiga(): func() print("获得Tiga的力量") return tiga def Dyna(func): print("给我力量吧,Dyna") def dyna(): func() print("获得Dyna的力量") return dyna def Gaia(func): print("给我力量吧,Gaia") def gaia(): func() print("获得Gaia的力量") return gaia @Tiga @Dyna @Gaia def Z(): print("变身") Z() # 输出结果 # 给我力量吧,Gaia # 给我力量吧,Dyna # 给我力量吧,Tiga # 变身 # 获得Gaia的力量 # 获得Dyna的力量 # 获得Tiga的力量

4.2,解除装饰器

from functools import wraps def light(func): print("获得神光棒x1") @wraps(func) def tiga(): func() print("我是光之巨人") return tiga @light def person(): print("我是某胜利队队员大骨") person() # 输出结果 # 获得神光棒x1 # 我是某胜利队队员大骨 # 我是光之巨人 DaGu=person.__wrapped__ DaGu() # 输出结果 # 获得神光棒x1 # 我是某胜利队队员大骨

Python

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:利用ESP8266测量模块来设计远距离反射式光电检测 : ITR8307
下一篇:深入理解JAVA中MyBatis框架(1)
相关文章