闭包函数
闭包函数定义
-
必须是函数内嵌函数
-
内嵌函数必须引用外函数的变量
-
外函数返回内嵌函数的函数名
def otter():
name = 'Gredae'
def inner(): # 外层函数包了个内层函数
print(name) # 内层函数引用了外层函数的变量
return inner # 外层函数返回内层函数的函数名
f = otter() # 用f变量来接收inner函数的地址
f() # 实际上是调用inner()函数
闭包函数的作用
可以使用函数闭包来实现一个函数的装饰器
函数装饰器的条件
- 不能改变原来函数的代码
- 为函数添加新的功能
- 不能改变函数的调用方式
装饰器的简单使用
计算函数运行的时间:
import time
def deco(func): # func = index
"""装饰器函数"""
def inner():
start = time.time()
func() # index
end = time.time()
print(end - start)
return inner
@deco # 如果在被装饰的函数上方写了语法糖就可以代替下面的 index = deco(index)
def index():
"""被装饰的函数"""
time.sleep(1)
print('hello, index')
index = deco(index) # index = inner 如果上面写了@deco语法糖就可以代替这一行
index() # 实际上执行的是inner函数
上面的是双层装饰器
三层装饰器饰装饰装饰器
def auth(engine):
def login(func):
def inner(*args, **kwargs): #将可变长参数传递进来
# 登录功能
if engine == 'file':
username = input('usrename:')
pwd = input('pwd:')
if username == 'Gredae' and pwd == '123':
print('登录成功')
res = func(*args, **kwargs) #传递不定长实参
return res
else:
print('登录失败')
elif engine == 'db':
print('账号密码来自于数据库,非法请求')
return inner
return login
@auth('file') # 三层装饰可以使用语法糖来传值
def login():
print('欢迎你!')
login() # inner()
迭代器
更新换代, 重复, 基于上一次的结果推出下一次的结果
迭代:具有__iter__方法
可迭代 | 不可迭代 |
---|---|
字符串、列表、字典、元祖、集合、文件 | 数值对象、函数 |
例如:
s = 'Gredae'
s_iter = s.__iter__()
print(s_iter.__next__()) # G ## 基于索引(基于上一次结果)通过__next__进行迭代
print(s_iter.__next__()) # r
print(s_iter.__next__()) # e
print(s_iter.__next__()) # d
迭代器对象:具有__iter__以及__next__方法
迭代对象除了文件是迭代对象之外都不属于迭代对象
迭代循环——for循环(解决了不依赖索引取值)
lt = [1,2,3,4]
lt_iter = lt.__iter__() ## 也可以这样定义迭代对象: lt_iter = iter(lt)
while True:
try:
print(lt_iter.__next__()) ##这句话一定会报错 也可以这样迭代: next(lt_iter)
except StopIteration: ## 当lt_iter迭代到没有元素的时候就会报错
break
for i in lt: # 可迭代对象;迭代器对象 # 不依赖索引取值,而是迭代取值
print(i)
- 首先使用iter把lt变成迭代器对象;对于文件也要使用iter方法吧文件再一次iter下
- 然后使用next方法进行迭代取值
- 判断StopIteration异常,遇到异常终止
迭代器对象一定是可迭代对象; 可迭代对象不一定是迭代器对象
生成器
在 Python 中,使用了 yield 的函数被称为生成器(generator)
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
例如,可以使用生成器生成一个斐波那契数列
def fibonacci(n): # 生成器函数 - 斐波那契
'''生成斐波那契'''
a, b, counter = 1, 1, 0
while counter < n:
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
while True:
try:
print(next(f), end=" ")
except StopIteration:
break