迭代函数
斐波那契数列 装饰器
1.回调2.闭包3.装饰器4.装饰器传参
4.1单个参数4.2多个参数 内置装饰器(了解)
1.property2.classmethod3.staticmethod 上次练习答案练习结束语下篇预告
迭代函数之前提到函数中有一个关键字是return,他的作用是结束函数并返回一个值,而yield也有类似功能,他的作用是暂停函数,返回一个生成器对象。
def fun1():
print(1)
yield "这是数值1"
print(2)
yield "这是数值2"
a = fun1() # 不执行函数内容,返回一个生成器对象
# 通过next方法迭代生成器对象去获取yield的返回值
print(next(a)) # 1 这是数值1
print(next(a)) # 2 这是数值2
# 当然可以用next方法迭代也就可以用for迭代
for i in fun1():
print(i)
斐波那契数列
利用迭代函数计算斐波那契数列。
a = 1 b = 1 a, b = b, a+b
使用这三个语句就可以得到数列中的任意值,以下是我写的斐波那契数列函数:
def fib(n=10):
# num表示当前迭代至斐波那契数列第num个数
# n表示求斐波那契数列的第n个数字
a, b, num = 1, 0, 1
if n == 0:
return 1
while num <= n:
a, b = b, a+b
yield b
num += 1
for i in fib(10):
print(i)
装饰器
作用:在不改变函数本身的同时,给函数加功能。
就像游戏中角色可以加装备一样,函数可以加功能。
装饰器 = 闭包 + 回调
回调是把一个函数体作为另一个函数的参数。
def fun1():
print("这是fun1()")
def fun2(f):
f() # 函数、方法
print("这是fun2()")
# 函数不加括号就是函数体
fun2(fun1)
"""这是fun1()
这是fun2()"""
2.闭包
闭包是外层函数返回内层函数的函数体。
def fun1():
def fun2():
print("fun2()被调用了")
return fun2
f = fun1()
f() # fun2()被调用了
3.装饰器
加上闭包和回调就可以得到装饰器。当然装饰器可以多个这里仅展示1个的情况。
def fun1(f):
def fun2():
f()
print("还特别爱吃")
return fun2
# 普通函数
@fun1 # @fun1() == fun1(fun)
def fun():
print("ice不仅长得帅")
fun()
"""ice不仅长得帅
还特别爱吃"""
其中@fun1就代表着定义装饰器,其含义等同于fun1(fun),并且在程序运行时会自动执行该语句。同时在fun1中返回的函数体会赋值给使用装饰器的函数名也就是fun,这样就可以做到给函数加装备了。
@fun1
def fun3():
print("fun3")
fun3()
# fun3
# 还特别爱吃
可以看出这个装饰器就像装备一样可以给所有函数装上。
4.装饰器传参当原函数需要传多个参数时,装饰器内部也需要接收多个参数,因此我们可以用元组接收多个参数。
4.1单个参数def fun1(f):
def fun2(n):
f(n)
print("还特别爱吃")
return fun2
@fun1
def fun(n):
print(f"ice很帅,颜值能打{n}分")
fun(100)
"""ice很帅,颜值能打100分
还特别爱吃"""
4.2多个参数
def fun1(f):
def fun2(*args):
f(*args) # 此处*是元组拆包
print("还特别爱吃")
return fun2
@fun1
def fun(*args):
print(f"ice很帅,颜值能打{args}分")
fun(100, 2, 1, 3)
"""ice很帅,颜值能打(100, 2, 1, 3)分
还特别爱吃"""
内置装饰器(了解)
内置装饰器是针对类的。
1.property对于无参方法。
class Person:
def __init__(self):
self.name = "ice"
self.age = 18
@property # 通过调用属性一样调用方法
def sleep(self):
print("sleep")
ps = Person()
ps.sleep
2.classmethod
返回类本身。
@classmethod
def study(self):
print(f"study{self}")
ps.study() # study
3.staticmethod
静态方法。
@staticmethod
def staticf():
print("static")
Person.staticf() # static
上次练习答案
import time
from decimal import Decimal
# 测试列表推导和不用列表推导那一种速度更快
class Runtime:
def __init__(self):
pass
def __enter__(self):
self.start = time.time()
return self.start
def __exit__(self, exc_type, exc_val, exc_tb):
self.end = time.time()
self.run = self.end - self.start
print(f"程序运行了{self.run}")
data = []
with Runtime():
for i in range(100000):
data.append(i)
with Runtime():
data1 = [i for i in range(100000)]
# range不可以使用小数做步长,实现一个可迭代对象,可以实现小数步长
class Number:
def __init__(self, start, end=None, step=None):
self.start = start
if step is None:
self.step = 1
else:
self.step = step
if end is not None:
self.end = end
else:
self.start = 0
self.end = start
def __iter__(self):
return self
def __next__(self):
start = self.start
if self.start >= self.end:
# 主动报错 结束,类似列表一样当对列表执行多次next而超过时也会报出该错误
raise StopIteration
self.start = Decimal(str(self.step)) + Decimal(str(self.start))
return start
for i in Number(1, 2, 0.1):
print(i)
for i in Number(0, 10):
print(i)
for i in Number(10):
print(i)
练习
本次无练习。
结束语
ps:现在关注我,以后就是老粉啦!!!
筛选出13开头的手机号怎么做呢?



