#迭代器
#拥有__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()