day12_装饰器迭代器生成器递归

本文深入解析装饰器的实现、递归函数的运用以及迭代器和生成器的内在机制,包括如何创建迭代器、生成器的工作原理和实战练习,助您提升编程技能。

回顾

  1. 函数就是变量

    定义函数就是定义类型是function的变量,函数名就是变量名。变量能做的事情,函数都能做

  2. 实参高阶函数

    max、min、sorted.

    max(序列,key = 函数),min(序列,key = 函数),sorted(序列,key = 函数)

    map

    map(函数,序列1)

    map(函数,序列1,序列2,序列3……)

    reduce合并一堆数据

    reduce(函数,序列,初始值)

    函数的要求:两个参数

新知识

装饰器

递归函数

迭代器和生成器

在函数中有错误时,只要没有调用,就不会报错

1. 迭代器

1)什么是迭代器(iter)

迭代器是容器型数据类型(序列),迭代器无法直接获取所有元素,也不能统计元素个数。

获取迭代器中的元素是会导致这个元素从迭代器中消失的。(元素取一个就少一个)

2)创建迭代器

创建迭代器只有两种方式:a.讲其他序列转换成迭代器; b.创建生成器

iter1 = iter('abr')
print(iter1)  #<str_iterator object at 0x0000019F27CAE860>

iter2 = iter([1,2,3,4,5])
print(iter2)  #<list_iterator object at 0x0000019F29ABC780>

iter3 = iter([{'a':10},{'b':20}])
print(iter3)  #<list_iterator object at 0x0000024CB503E6A0>
3)获取迭代器中的元素
a) 获取单个元素:next(迭代器)
print(next(iter1))
print(next(iter1))
print(next(iter1))
#a
#b
#r
b)遍历
for x in iter2:
    print(f'x:{x}')
#x:1
#x:2
#x:3
#x:4
#x:5

2.生成器

1)概念

生成器从获取数据和保存特点来看,就是迭代器
生成器保存数据的本质不是保存数据本身,而是保存产生数据的算法

2)创建生成器

调用带有yield关键字的函数就可以得到一个生成器。

调用带有yield关键字的函数的时候不会执行函数体,也不会获得函数返回值,只是单纯的创建一个生成器(函数中的yield放在哪儿没有关系)

def func1():
    yield
    print('====')
    return 100
result = func1()
print(result)
print(f'result:{result}')
3)确定生成器的元素 - 生成器可以创造的数据

一个生成器能产生多少个数据,就看这个生成器对应的函数,执行完函数体会遇到几次yield

每次遇到yield的时候,yield后面的数据就是产生的数据

def func2():
    yield 100
    yield 200
    yield 300
result = func2()
print(next(result))
print(next(result))
print(next(result))
4)生成器产生数据的原理

当通过生成器对象获取元素(不管以什么样的方式获取)的时候,系统会自动执行生成器对应的函数,执行函数的时候不会直接将整个函数执行完,而且每次在执行yield的时候就会停下来,并且将yield后面的数据作为结果返回。

下次再获取元素的时候,从上次结束的位置开始执行。

def func3():
    print('11111111')
    yield 100
    print('22222222')
    yield 200
    print('33333333')
    yield 300
    print('44444444')
    yield 400
result = func3()
print(next(result))
print(next(result))
print(next(result))
print(next(result))

#11111111
#100

#22222222
#200

#33333333
#300

#44444444
#400

区别

def func5():
    yield 10
    yield 20
    yield 30
print(next(func5()))    #10
print(next(func5()))    #10
result = func5()
print(next(result))   #10
print(next(result))   #20
练习:写一个创建学生学号的生成器,要求产生的学号前缀是python,后面是指定范围的值。

26 ~ 56 -> python0026 ~ python0056

def study_num(subject='python', start=26, end=56):
    for x in range(start, end):
        yield f'{subject}{str(x).zfill(4)}'


creater = study_num()
print(next(creater))
for _ in range(3):
    print(next(creater))
java = study_num('java', 1, 50)
print(next(java))

3.装饰器

1)什么是装饰器

装饰器 = 实参高阶函数+返回值高阶函数+糖语法(装饰器的本质就是函数)

作用:给已经定义好的函数添加功能

2)无参装饰器的实现方法

装饰器的工作原理:将需要添加功能的函数传给装饰器,装饰器创建一个保留原函数功能并且添加新功能的一个新的函数
将添加完功能的新函数返回,最后用新的函数替换原来的函数

装饰器的套路:

def 函数名1(参数1:function):
	def 函数名2(*args, **kwargs):
        添加新的功能
        result = 参数1(*args,**kwargs)
        return result
    return 函数名2

函数名1 - 装饰器功能对应的名字

参数1 - 类型是function,指向需要添加功能的原函数,习惯命名成fn

函数名2 - 指向添加完功能的新函数,习惯命名为new_fn

def 装饰器(fn):
    def new_fn(*args,**kwargs)
		新功能
        result = fn(*args,**kwargs)
        return result
    return new_fn
def add_100(fn):
    def new_fn(*args,**kwargs):
        result = fn(*args,**kwargs)
        if type(result) in (int,float):
            return result+100
        return result
    return new_fn

练习 :写一个装饰器,将函数的返回变成字符串

# 练习 :写一个装饰器,将函数的返回变成字符串
# 100->‘100’
# None->'None'
# False->'False'

def to_str(fn):
	def new_fn(*args,**kwargs):
        result = fn(*args,**kwargs)
        return str(result)
    return new_fn
    
4.递归函数

在定义函数的时候调用函数本身,这种函数就是递归函数

理论上,循环能做的事情递归都能做,能用循环实现就不要用递归

第一步:找临界值,在临界值的位置结束函数(相当于循环结束的条件)
第二步:找关系,找上一次循环结束的结果和当次循环结束的结果的关系
第三步:假设函数功能已经实现,通过关系用f(n-1)实现f(n)的功能

使用递归解决循环问题的时候。内存和cpu的消耗会随着循环次数的增加而不断增加

# 1.计算1+2+。。。。+100
def sum1(n):
    if n == 1:
        return 1
    else:
        return sum1(n - 1) + n


print(sum1(100))
# Fibonacci
def F(n):
    if n==1 or n==2:
        return 1
    else:
        return F(n-1)+F(n-2)

print(F(5))

明天:

模块和包、常用模块(时间相关模块,hashlib、random)

异常捕获

作业

  1. 为函数写一个装饰器,在函数执行之后输出 after
 def after(fn):
     def new_fn(*args,**kwargs):
         result = fn(*args,**kwargs)
         print('after')
         return result
     return new_fn
  1. 为函数写一个装饰器,把函数的返回值 乘2再返回值
 def double_num(fn):
     def new_fn(*args, **kwargs):
         result = fn(*args, **kwargs) * 2
         return result
     return new_fn
  1. 写一个装饰器@tag要求满足如下功能:
@tag
def render(text):
    # 执行其他操作
    return text

@tag
def render2():
    return 'abc'

print(render('Hello'))   # 打印出: <p>Hello</p>
print(render2())     # 打印出: <p>abc</p>
def tag(fn):
    def new_fn(*args, **kwargs):
        result = '<p>'+str(fn(*args, **kwargs))+'</p>'
        return result
    return new_fn
  1. 写一个创建一副扑克牌的生成器。
 def poker():
     print('扑克牌如下:')
     for poker_flower in ['方块', '红桃', '梅花', '黑桃']:
         poker_single = [poker_flower+str(tmp) for tmp in range(2, 11)]
         poker_single+=[poker_flower+tmp for tmp in ['J','Q','K','A']]
         yield poker_single
     yield ['JOKER','joker']
 
 pokers = poker()
 print(next(pokers))
 print(next(pokers))
 print(next(pokers))
 print(next(pokers))
 print(next(pokers))
  1. 使用递归函数画出以下图形:
 n = 5
 *****
 ****
 ***
 **
 *
 
 
 n = 4
 ****
 ***
 **
 *
def star(n):
    if type(n)!=int:
        return '输入不合法!'
    if n==1:
        print('*')
        return 0
    else:
        print('*'*n)
        return star(n-1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值