三大神器
- 迭代器
# 1 . 迭代器(iter)
'''
迭代器是容器;程序中无法直接创建一个迭代器, 只能将别的序列转换成迭代器
特点: 打印迭代器无法查看所有的元素.也无法获取元素的个数;每次只能获取最前面那个元素,而且取一个元素就少一个元素
'''
list1 =[1,2,3,4]
it = iter(list1) # 创建迭代器对象
print (next(it)) # 输出迭代器的下一个元素 # 1
print (next(it)) # 2
print(list1) #[1, 2, 3, 4]
print(list(it)) #[3, 4]
i1 = iter('abc123')
print(i1) #<str_iterator object at 0x000001CB19E07F10>
# print(len(i1)) 会报错
i3 = iter({'a':10,'b':20})
print(i3) #<dict_keyiterator object at 0x00000274B7154450>
print(next(i3)) #a
print(next(i3)) #b
i4 = iter('hello')
for x in i4:
print('x:',x)
# print(next(i4)) #报错
print(list(i4)) #[]
# 2.查 - 获取元素
# 迭代器不管以什么样的方式获取到了某个元素, 那么这个元素一定会从迭代器消失
'''
1) 查单个: next(迭代器) - 获取迭代器中最前面的元素
注意:取完了,继续取会报错
2) 遍历
'''
遍历:
会输出:1到20
- 生成器
# 1.什么是生成器
'''
生成器也是容器;其他容器是直接保存多个数据,生成器保存的是产生多个数据的算法
生成器获取数据的方式的特点和迭代器一样.
'''
# 2.创建生成器
'''
调用一个带有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=" ")
# except StopIteration:
# sys.exit()
# a = fibonacci(10) #会输出10个数就是数列过程
# lizi:
def func1():
yield
print('+++')
print('===')
return 100
result = func1()
print('result:',result) #<generator object func1 at 0x000002449426B6D0>
# 3.控制生成器产生数据的个数和对应的值
'''
一个生成器产生的数据的个数和值由创建生成器调用的那个函数的函数体在执行的时候
会遇到几次yield的次数和yield后面的值决定
'''
def create1():
yield 100
yield 200
yield 300
gen1 = create1()
# print(list(gen1)) #[100, 200, 300]
print(type(gen1)) #<class 'generator'>
print(next(gen1)) #100
print(next(gen1)) #200
print(next(gen1)) #300
# print(next(gen1)) #StopIteration
def create2():
x=0
while True:
yield x
x += 1
gen3 = create2()
print(next(gen3))
for _ in range(10):
print(next(gen3))
gen4 = create2()
print(next(gen4))
# 练习: 写一个生成器可以创建PYTHON班级的学生的学号,学号的范围是:python0001 ~ 1000
#进阶: 可以产生
def funcc():
x = 1
n= 0
count = 0
while n < 1000:
count = ('python' + '0'*(4-len(str(x))) + str(x))
n += 1
x += 1
yield count
gen5 = funcc()
print(next(gen5))
def study_():
for i in range(1,1001):
yield f'python{i:0>4}'
gen8 = study_()
print(next(gen8))
print(next(gen8))
# 4. 生成器创建数据的原理
'''
每次获取生成器的数据的时候, 就会去执行创建这个生成器的函数体,但是每次执行
都只会执行一个yield
'''
def func2():
print('=====')
yield 100
print('++++')
yield 200
print('!!!!!')
yield 300
gen4 = func2()
print(next(gen4))
print(next(gen4))
print(next(gen4))
result = map(lambda item: item*2,'abc')
print(result)
print(next(result))
print(next(result))
三.装饰器
# 1.什么是装饰器 - 给已经定义好的函数添加功能的工具
import time
'''
装饰器就是一个函数,这个函数既是实参高阶函数,又是返回值高阶函数.
'''
# 2.给函数添加功能
# 解决方案: 直接修改原函数
#练习:给函数添加功能,统计函数的执行时间
# def hello():
# strat = time.time()
# print('hello world!')
# end = time.time()
# print(f'总时间:{end -strat}')
# hello()
# def factorial(n):
# start = time.time()
# s = 1
# for x in range(1,n+1):
# s *=x
# print(s)
# end = time.time()
# print(f'总时间:{end - start}')
# factorial(10)
# 解决方案二:
def total_time(fn,*args,**kwargs):
start = time.time()
fn(*args,**kwargs)
end = time.time()
print(f'总时间:{end - start}')
def factorial(n):
start = time.time()
print(start)
s = 1
for x in range(1,n+1):
s *=x
print(s)
end = time.time()
print(end)
print(f'总时间:{end - start:,.18f}')
total_time(factorial,10)
# 解决方案三
# 装饰器
四:无参装饰器
# 1.无参装饰器
'''
语法:
def 装饰器名1(原函数):
def 添加完功能的新函数(*arg,**kwargs):
调用原函数
添加新功能
return 添加完功能的新函数
def 装饰器名(old_f):
def new_f(*arg,**kwargs)
result = old_f(*arg,**kwargs)
新增功能
return 返回值(也要根据情况,一般是result)
return new_f
装饰器名 - 根据新增功能
'''
# 练习1: 在函数调用之前,打印'前锋教育欢迎'
def welcome(old_f):
def new_f(*args,**kwargs):
print('前锋欢饮')
result = old_f(*args,**kwargs)
return result
return new_f
@welcome
def hello():
print('hello world')
def count_1(num1,num2):
return num1 +num2
hello()
print('he',count_1(10,20))
# 练习: 函数调用结束end答应'===end ==='
# 2 .将返回值为数字的函数的返回值变成原来的返回值的100被
def welcome1(oldf):
def newf(*args,**kwargs):
result = oldf(*args,**kwargs)
print('===end===')
return result
return newf
@welcome1
def hello1():
print('hello world111')
hello1()
s = hello1()
print(s)
## ===end===
## None 这样就不一样,自己要注意逻辑顺序
def welcome2(oldf1):
def newf1(*args,**kwargs):
result = oldf1(*args,**kwargs)
if result.isdigit(): #if type(result) in (int,float)
return eval(result)*100
else:
return result
return newf1
@welcome2
def turn1():
return 'abc123'
turn1()
print(turn1())
五.有参装饰器
"""
Autor:wxk
DATE:2022/4/26 16:51
"""
'''
有参数装饰器语法细化:
def 装饰器名称(参数列表):
def 午餐装饰器(f):
def new_f(*arg,**kwargs)
新增功能
return result
return new_f
return 午餐装饰器
参数列表 - 看实现装饰器新增功能需不需要额外的数据需要几个
'''
# 写一个装饰器将返回值是数字的函数的返回值变成原来返回值的定制倍数
def magnify(n):
def temp(f):
def new_f(*args,**kwargs):
result = f(*args,**kwargs)
if type(result) in (int,float):
return result*n
return result
return new_f
return temp
@magnify(5)
def turn1():
return 123
print(turn1()) #不加括号可能出问题
# 练习2:写一个装饰器,用法如下
# 没有装饰器返回值如果是: 100
# 没有装饰器返回值如果是: 'abc'
def magnify1(n1,n2):
def temp(f):
def new_f(*args,**kwargs):
result = f(*args,**kwargs)
if type(result) in (int,float):
return f'<{n1}>{result}</{n1}>'
return f'<{n2}>{result}</{n2}>'
return new_f
return temp
@magnify1('a','p')
def duke():
return 'acd'
print(duke())
# 练习3: 写一个装饰器(返回值是数字的函数),用法如下
# 12-> +100 -> 112
# 12 -> - 20 > -8
# 12-> * 3 -> 36
def magnify3(n1,n2):
def temp(f):
def new_f(*args,**kwargs):
result = f(*args,**kwargs)
if '+' == n1:
return f'{result + n2}'
elif '-' == n1:
return f'{result - n2}'
elif '*' == n1:
return f'{result * n2}'
elif '/' == n1:
return f'{result / n2}'
return new_f
return temp
@magnify3('/', 3)
def duke1():
return 12
print(duke1())
def magnify4(n1,n2):
def temp(f):
def new_f(*args,**kwargs):
result = f(*args,**kwargs)
return eval(f'{result}{n1}{n2}')
return new_f
return temp
@magnify4('+',100)
def duke2():
return 12
print(duke2())