python_(装饰器,闭包,迭代器,生成器)

本文深入探讨了Python编程中的关键概念:装饰器、闭包、迭代器和生成器。装饰器允许在不修改原始函数的情况下扩展其功能;闭包则涉及函数嵌套和非局部变量的使用;迭代器提供了对可迭代对象的逐项访问方式;生成器则是一种节省内存的迭代机制,支持按需计算。文章通过实例详细解释了这些概念,并展示了它们在实际编程中的应用。
摘要由CSDN通过智能技术生成

1.装饰器

原因:“开放封闭”:对扩展开发;对已实现的功能封闭
含义:不修改原函数的前提下,增加函数的功能,只能在函数运行前或者运行后添加。

#基本结构
def check_logic(fun):
    def inner():
        #动作1
        #动作2
        fun()
    return inner

@check_logic #即:f1=check_logic(f1)
def f1():
    print("hello")
#带多个参数的装饰器
def xxx(func):
    def yyy(*args,**kwargs):#用来接收不确定个数的参数
        ret=func(*args,**kwargs)#将接收到的参数进行拆包,传递到原函数中
        return ret
    return yyy

@xxx
def a(num):
    print("___1",num)
    return 100,200,300

@xxx
def b():
    print("-----2")

print(a(100))
#带有多个参数的类装饰器
class Test(object):
    def __init__(self,num):
        print("___init")
        self.__num=num
    def __call__(self,func):
        #类中带有__call__,可以对实例对象直接调用:实例对象(参数)
        print("__call")
        self.__func=func
        return self.call_old_func
    def call_old_func(self):
        print("___功能1")
        self.__func()
        print("__功能2")

@Test(100)
def a():
    print("___test")

print(a())

参考:

https://www.bilibili.com/video/BV1Pu411v7zb?p=15

2.闭包
什么是闭包?
1.函数A中嵌套定义了函数B,且函数B用到了函数A的变量或者形参,那么函数B及函数A中的变量或者形参称之为闭包。外部函数返回内部函数的引用

def counter(start=0):
    def add_one():
        nonlocal start#添加nolocal 可以让外部变量在闭包的内部函数中进行修改
        start+=1
        return start
    return add_one

c1=counter(5)#创建一个闭包
print(c1())#相当于:print(counter(5)())

c2=counter(20)#创建另一个闭包
print(c1()) #闭包不会释放变量,会永久储存
print(c2())
# 1.闭包的格式
# 2.闭包不会释放变量,会永久储存,占用存储空间
# 3.nonlocal的用法
# 4.对象:N个属性+N个函数;
#	闭包:N个属性+一个函数(一般来讲)


3.迭代器:对可迭代对象进行记录的方式。


# 1.迭代器与可迭代对象
num=[11,2,33,44,55] #可迭代对象:能用for循环遍历的
num_iter=iter(num) #取num这个可迭代对象的迭代器

num1=next(num_iter) #提取迭代器的下一个数据
print(num1)

for n in num:
    print(n)
    
#for循环可以过程可以通过iter()和next()函数来实现
#即:先调用iter(),将num当作实参,得到num的迭代器
#    再调用next(),对迭代器进行取值

# 2.迭代器中异常StopIteration的处理
num=[11,2,33,44,55] #可迭代对象:能用for循环遍历的
num_iter=iter(num) #迭代器

while True:
    try:
        n=next(num_iter)
        print(n)
    except StopIteration as ret:
        print(ret)
        break
# 3.自定义可迭代对象和迭代器
class My_list(object):
    def __init__(self):
        self.items=[]
    def add(self,val):
        self.items.append(val)
    def __iter__(self):
        # 1.标记当前类创建出来的对象一定是 可迭代对象
        # 2.当调用iter()函数的时候 这个方法会被自动调用,返回它自己指定的那个迭代器
        return MyIterator()


class MyIterator(object):
    def __init__(self):
        pass
    def __next__(self):
        # 1.标记当前类创建出来的对象一定是 迭代器
        # 2.当调用next()函数的时候 这个方法会被自动调用,返回一个数据
        pass
    def __iter__(self):
        pass

mylist=My_list() #可迭代对象
mylist.add(5)
mylist.add(11)
mylist.add(90)
mylist.add(44)

mylist_iter=iter(mylist.items) #生成迭代器
print(next(mylist_iter))
# >>5

4.生成器
Python中,一边循环一边计算的机制,称为生成器:generator。

# 1.创建生成器的方式1:将列表的[]改为()
nums=[x for x in range(5)]#列表
print(nums)
#[0, 1, 2, 3, 4]

nums1=(x for x in range(5))#生成器:只记录生成数据的方式,而不是事先存储这些数据(一般用于数据不确定时)
print(nums1)
#<generator object <genexpr> at 0x000001EA195C14F8>

# 2.创建生成器的方式2:函数定义中包含yield关键字
def fib_generator():
    num1=1
    num2=1
    while True:
        temp_num=num1
        num1,num2=num2,num1+num2
        yield temp_num

fib=fib_generator() #如果一个函数中有yield,那么fib_generator()就变成了创建一个生成器对象
print(fib) #<generator object fib_generator at 0x0000019550D314F8>

#通过next函数调用
num1=next(fib)#把yield关键字后的数值 temp_num 返回,当作next()的返回值
print(num1)#1 

num2=next(fib)
print(num2)#1

num3=next(fib)
print(num3)#2

# yield关键字
# 1.只有有yield关键字,虽然是调用函数,但实际上是创建了一个生成器对象
# 2.通过next调用生成器,可以让带有 yield 的 def 的代码块开始执行
# a.在每次调用next()的时候执行,遇到yield语句返回,把yield关键字后的数值返回,当作next()的返回值
# b.再次执行时从上次返回的yield语句处继续执行,直到遇到下一次yield为止,把yield关键字后的数值返回,当作next()的返回值
# 3.函数中既有 yield,又有return
def fib_generator():
    num1=1
    num2=1

    temp_num=num1
    num1,num2=num2,num1+num2
    yield temp_num

    temp_num=num1
    num1,num2=num2,num1+num2
    yield temp_num

    temp_num=num1
    num1,num2=num2,num1+num2
    yield temp_num

    return "3个斐波那契数列"

fib=fib_generator() #如果一个函数中有yield,那么fib_generator()就变成了创建一个生成器对象

num1=next(fib)
print(num1)#1

num2=next(fib)
print(num2)#1

num3=next(fib)
print(num3)#2
#
#把return的数值用 异常 暂时存储起来
num4=next(fib)
print(num4) #StopIteration: 3个斐波那契数列

try:
    print(next(fib))
except StopIteration as ret:
    print(ret.value) #有return,封装到异常对象的value值中
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值