迭代器
拥有__iter__方法和__next__方法的对象就是迭代器
迭代是访问集合元素的一种方式,可以将某个数据集内的数据“一个挨着一个的取出来”,就叫做迭代。
斐波拉契数列
class Fib():
def __init__(self,num):
self.num=num
self.a=1
self.b=1
self.current=1
def __iter__(self):
return self
def __next__(self):
if self.current<=self.num:
temp=self.a
self.a,self.b=self.b,self.a+self.b
self.current+=1
return temp
else:
raise StopIteration
print(list(Fib(10)))
输出结果为:
生成器
一、生成器函数
一个包含yield关键字的函数就是一个生成器函数。并且yield不能和return共用,并且yield只能用在函数内。
def shenchan(n):
i=1
while i<=n:
yield i # yield返回值,并不会完全的结束函数,而是保存下来当前的状态,等到下次进入的时候,继续使用
i+=1
x=shenchan(5)
print(list(x))
输出结果为:
def hs():
for i in range(3):
yield "第%d个包子"%(i+1)
x=hs()
print(next(x))
print(next(x))
print(x.__next__())
输出结果为:
斐波那契数列
def g(get_month):
a=1
b=1
i=1
while i<=get_month:
yield a
a,b=b,a+b
i+=1
x=g(5)
print(list(x))
输出结果为:
二、send()
send获取下一个值得效果和next()基本一致,只是在获取下一个值得时候,给上一yield的位置传递一个数据。
使用send的注意事项
(1).第一次使用生成器的时候,使用next获取下一个值
(2).最后一个yield不能接受外部的值
求平均值
def g():
count=1
get_num=0
avg=0
toatl=0
while True:
get_num=yield avg
toatl=toatl+get_num
avg=toatl/count
count+=1
x=g()
next(x)
print(x.send(10))
print(x.send(20))
print(x.send(30))
输出结果为:
三、yield from
def g():
yield from "AB"
yield from range(5)
for x in g():
print(x)
输出结果为:
四、生成器表达式
格式:将列表推导式[]改为()即可。
a=("鸡蛋%d"%i for i in range(1,11))
print(a)
print(next(a))
print(a.__next__())
print(list(a))
输出结果为:
装饰器
一、闭包
在python中创建一个闭包一般有三个要求:
1.闭包函数必须有内嵌函数。
2.内嵌函数必须要引用外层函数的变量。
3.闭包函数返回内嵌函数的地址。
def waiceng(b):
a=3
def neiceng(x):
return x*a+b
return neiceng
x=waiceng(9)
print(x(5))
print(x(7))
输出结果为:
二、装饰器
1.装饰器函数的本质:一个闭包函数
2.装饰器的作用:在不修改原函数及其调用方式的情况下对原函数功能进行扩展。
3.格式:@装饰器名称。
获得程序运行的时间:
import time
def d(f):
def neibu():
t=time.time()
f()
t2=time.time()
print("时间{}".format(t2-t))
return neibu
@d
def func():
s=0
for i in range(10000000):
s+=1
print(s)
func()
输出结果为:
创建一个带参数和返回值的装饰器:
from functools import wraps
def acor(f):
@wraps(f)
def neibu(a,b):
print("*********")
d=f(a,b)
print("*********")
return d
return neibu
@acor
def func(a,b):
'''
adadadadadad
'''
c=a+b
return c
print(func(2,3))
print(func.__doc__)
输出结果为:
三、@property装饰器
1.@property内置装饰器函数,把一个方法调用方式变成属性调用方式。(将一个方法当成一个属性使用)。注意@property装饰器只能在面象对象中使用。
2.访问使用@property装饰器装饰的函数可以直接调用函数名。
3.@property装饰器只能修饰不带参数的放法。
求圆形的周长和面积。
from math import pi
class Circle():
def __init__(self,r):
self.r=r
@property
def zhouzhang(self):
return 2*pi*self.r
@property
def area(self):
return pi*self.r*self.r
y=Circle(3)
print(y.zhouzhang)
print(y.area)
输出结果为:
BMI指数计算
class A():
def __init__(self,name,t,g):
self.name=name
self.t=t
self.g=g
@property
def bmi(self):
return "{}的bmi指数是{}".format(self.name,self.t/(self.g**2))
a=A("lee",65,1.78)
print(a.bmi)
输出结果为:
扩展题:
编写一个集合的功能,将一个列表去重。
a=[7,4,5,6,2,5,6,2,4,6,1,3,5,1]
i=0
while i<len(a)-1:
j=i+1
while j<len(a):
if a[i]==a[j]:
del a[j]
continue
j+=1
i+=1
a.sort()
print(a)
输出结果为:
装饰器的练习:
输入菱形的上半部的行数,输出这个菱形。
ru(f):
def nb():
print('循环')
while True:
n=input("请输入菱形上半部分的行数:")
if n=="Q" or n=="q":
print("程序退出")
break
f(n)
return nb
def yanzheng(f):
def nb(n):
print("验证")
if n.isdigit():
n=int(n)
f(n)
else:
print("请输入整数")
return nb
@shuru
@yanzheng
def shuchu(n):
for i in range(n):
for j in range(n-(i+1)):
print(" ",end="")
for k in range(i*2+1):
print("*",end="")
print()
for i in range(n,0,-1):
for j in range(n-i):
print(" ",end="")
for k in range(i*2-1):
print("*",end="")
print()
shuchu()
输出结果为: