5.8笔记+day12作业

博客介绍了迭代器需有__iter__和__next__方法,生成器本质是迭代器,包含生成器函数和表达式,还说明了闭包和装饰器的概念、判断方法及作用。此外,布置了生成器相关作业,要求打印菱形,将逻辑分离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#迭代器
#拥有__iter__方法和__next__方法的对象就是迭代器

a=[1,2,3,4,5]
b=a.__iter__()
print(next(b))#1
#与print(next(b))作用相同
print(b.__next__())#2
print(next(b))#3
#如果迭代完还继续输出b的话,就会报错

#斐波那契函数迭代

class Fib():
    def __init__(self,num):
        self.num=num
        self.current=1
        self.a=1
        self.b=1
    def __iter__(self):
        return self
    def __next__(self):
        if self.current<self.num:
            ret=self.a
            self.a,self.b=self.b,self.a+self.b
            self.current+=1
            return ret
        else:
            raise StopIteration
for x in Fib(10):
    print(x)

#生成器,本质就是迭代器,包含生成器函数和生成器表达式
#包含yield关键字的就是一个生成器函数,并且yield不能与return共用

def hanshu():
    i=0
    while i<3:
        yield i
        i+=1
b=hanshu()
print(next(b))#0
print(next(b))#1
print(next(b))#2

def hanshu():
    yield 1
    yield 2
b=hanshu()
print(next(b))#1
print(next(b))#2

#send()获取下一个值的效果和next()基本一致,只是在获取下一个值的时候给上一个yield的位置传递一个数据

def jisuan():
    get_num=0
    count=1
    avg=0
    total=0
    while True:
        get_num=yield avg
        total=total+get_num
        avg=total/count
        count+=1
b=jisuan()
next(b)#第一次使用生成器的时候,是用next获取下一个值
print(b.send(10))#10.0
print(b.send(20))#15.0
print(b.send(30))#20.0

#yield from

def get1():
    for x in "asdfg":
        yield x
    for x in range(5):
        yield x
x=get1()
for i in x:
    print(i)

def get2():
    yield from "asdf"
    yield from range(5)
y=get2()
for j  in y:
    print(j)

#生成器表达式,将列表推导式的[]改成()即可

b=(i for i in range(10))
print(b)
for x in b :
    print(x)    

#装饰器

#闭包 有三个要求:
#1、闭包函数必须有内嵌函数
#2、内嵌函数必须要引用外层函数的变量
#3、闭包函数返回内嵌函数的地址(函数名称)

def func():
    name="qqq"
    def inner():
        print(name)
    return inner
f=func()
f()

#判断闭包函数的方法__closure__
#输出的__closure__有cell元素:是闭包函数def func():

def func():
    name="evo"
    def inner():
        print(name)
    print(inner.__closure__)
    return inner
f=func()
f()

#输出的__closure__没有cell元素:不是闭包函数

name="qww"
def func2():
    def inner():
        print(name)
    print(inner.__closure__)
    return inner
f2=func2()
f2()  

#装饰器 本质就是一个闭包函数,作用是在不修改原函数及调用方式的情况下对原函数的功能进行扩展
#固定格式:

def wrapper(f):
    def inner(*args,**kwargs):
        #被装饰的函数之前执行的代码
        ret=f(*args,**kwargs)#被装饰的函数
        #被装饰的函数执行之后的执行的代码
        return ret
    return inner
@wrapper
def fun(*args,**kwargs):
    print("zzz")

#例子

import time
def hehe(f):
    def haha():
        a=time.time()
        print("1111111")
        f()
        b=time.time()
        print("22222222",b-a)
    return haha
@hehe
def hs():
    print("开始")
    he=0
    for i in range(8):
        he+=i
    print("结束")
hs()

#创建一个带返回值的装饰器

import time
def timer(func):
    def inner():
        start=time.time()
        time.sleep(0.01)
        ret=func()#接受返回值
        end=time.time()
        print(end-start)
        return ret
    return inner
@timer
def fun():
    print("开始")
    return "结束"#设置返回值
ret=fun()
print(ret)

#创建一个带参数的修饰器

import time
def timer(func):
    def inner(s):#传递参数
        start=time.time()
        time.sleep(0.01)
        func(s)#传递参数
        end=time.time()
        print(end-start)
    return inner
@timer
def fun(s):
    print("xxx",s)
fun("ooo")

##定义一个可以传递任意参数的修饰器

import time
def timer(func):
    def inner(*args,**kwargs):
        start=time.time()
        time.sleep(0.01)
        func(*args,**kwargs)
        end=time.time()
        print(end-start)
    return inner
@timer
def fun(*args,**kwargs):
    print("传递过来的参数:",args,kwargs)
fun("ooo","zz",name="张三")

#@property内置修饰器函数,把一个方法调用方式变成属性调用方式,就是将一个方法当成一个属性使用

class People():
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height
    @property
    def bmi(self):
        return self.weight/(self.height**2)
p1=People("张三",70,1.73)
print(p1.bmi) 

#实例方法:指类中定义的普通方法,只有实例化对象后才可使用的方法,该方法的第一个形参接收的一定是对象本身!

class A():
    def __init__(self,name):
        self.name=name
    def ptt(self):
        print(self.name,"我来啦")
a=A("刘德华")
a.ptt()

#静态方法:可以有参数也可以无参数,一般用于和类对象以及实例对象无关的代码

class A():
    @staticmethod
    def show_menu():
        print("1楼,化妆品")
        print("2楼,洗衣机")
        print("3楼,电视机")
    def hanshu(self):
        print("你好")
a=A()
A.show_menu()
a.show_menu()
a.hanshu()
A.hanshu(a)

#类方法:无需实例化,可以通过类直接调用的方法,但方法的第一个参数接收的一定是类本身

class A():
    role="角色"
    @classmethod
    def hanshu(cls):
        print(cls.role)
a=A()
A.hanshu()
a.hanshu()

#作业

#迭代器练习
class SuShu():
    def __init__(self,start,end):
        self.start=start
        self.end=end
    def isSuShu(self,k):
        if k<2:
            return False
        for i in range(2,k):
            if k%i==0:
                return False
        return True
    def __iter__(self):
        for k in range(self.start,self.end+1):
            if self.isSuShu(k):
                yield k
for x in SuShu(1,10):
    print(x)

#生成器

def read_file(fpath):
    BLOCK_SIZE=6
    with open(fpath,"r") as f:
        while True:
            block=f.read(BLOCK_SIZE)
            if block:
                yield block
            else:
                return
import os
g=read_file(os.getcwd()+"\\dd")
for content in g:
    print(content)

(一)需求:打印菱形
1、空格、*号组成的菱形
2、输入菱形上半部分的行数即可打印。
3、支持循环输入
4、输入“q”、“exit”可以退出循环

简单的分析:
1、打印菱形:print_diamond(n)
2、验证输入是否是合法数字:@verify_number
3、永循环和n输入:@forever
这3层逻辑,分离开来。

from sys import stdout


def forever(fun):
    def inner():
        print("循环")
        while True:
            # nonlocal n
            n = input("请输入菱形上部的正三角的行数:")
            if n == "q" or n == "exit":
                print("程序已退出!")
                break
            fun(n)

    return inner


def verify_number(fun):
    def inner(n):
        print("验证输入的有效性")
        if isinstance(n, int) or n.isdigit():  # 判断字符串是否为纯整数字组成
            n = int(n)
            fun(n)
        else:
            print("请输入整数!!!")

    return inner


@forever
@verify_number
def print_diamond(n):
    for i in range(1, n + 1):
        for j in range(1, n - i + 1):
            stdout.write(' ')
        for k in range(1, 2 * i - 1 + 1):
            stdout.write('*')
        print()
    for i in range(1, n - 1 + 1):
        for j in range(1, i + 1):
            stdout.write(' ')
        for k in range(1, 2 * (n - i) - 1 + 1):
            stdout.write('*')
        print()


print_diamond()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值