函数高级部分,装饰器、生成器、命名空间、作用域
命名空间:
变量创建时,做两件事,一、开辟内存空间放入变量的值。二、开辟另一块内存,叫命名空间保存变量名和对应内存地址的映射关系。
a = 1 ===> 一、开辟内存 保存 1 ,地址为12312123. 二、在命名空间中保存 a ---> 12312123.被写做{a:1}.
locals() 调用现在处于对应局部的命名空间中的所有内容。
globals()调用全局的命名空间中的所有内容。
dir(builtins) 调用全部内置函数的命名空间中的内容。
作用域变量查找顺序:
LEGB:
locals
enclosing
globals
builtins
闭包:
外部函数返回内部函数名,内部函数调用外部函数变量,这样的函数叫函数的闭包。
def foo():
a = 2
def bar():
print('bar a :',a)
return bar
f = foo()
f()
装饰器:
开放封闭原则:
封闭:对已经实现的代码一般不修改
开放:对现有的功能扩展开发
对现有的函数添加功能,并且不改变调用方式。、
现有foo函数和bar 函数,给bar函数添加foo函数中的功能, 并且不改变调用方式。
def foo(fun):
def add_func(*args,**kwargs):
print('foo')
fun(*args,**kwargs)
return add_func
@foo # bar = foo(bar)
def bar(name):
print('bar',name)
bar('qianlei')
装饰器添加参数
def foo(type):#装饰器参数
if type == 'qq':
print('qq')
def outer(func):#添加功能的函数
def inner(*args,**kwargs):#添加功能函数的参数
print('foo')
func(*args, **kwargs)
return inner
return outer
@foo('qq') # bar = foo('qq')(bar)
def bar(name):
print('bar',name)
bar('qianlei')
网站登陆,函数实现装饰器登陆功能:
网站登陆,如果需要给装饰器添加参数,就需要将装饰器函数添加一层函数
user_status = False
def dec_arg(arg):
print("装饰器参数",arg)
def login(func):
def add_fun(*args,**kwargs):
global user_status
u = 'qianlei'
p = 'abc123'
if user_status == False:
user = input('输入用户名')
pass_word = input('输入密码')
if user == u and pass_word == p:
user_status = True
print('welcome')
else:
print('输入错误')
exit()
else:
print('用户已登陆')
func(*args,**kwargs)
return add_fun
return login
@ dec_arg('qq') # henan = dec_arg('qq')(henan)
def henan():
print('欢迎进入河南')
列表生成式
l = [i for i in range(10)]
l1 = [i if i<5 else i*i for i in range(10)]
print(l)
print(l1)
列表生成式改为圆括号,就是生成器。
l2 = (i for i in range(5))
print(l2)
print(next(l2))
print(next(l2))
列表生成式 函数 中含有yield,就被看做列表生成式。
def yield_test():
x = 0
while x<10:
x += 1
print('before yield')
res = yield x
print('behind yield')
print(res)
return 'over.'
g = yield_test() # 产生生成器。
print(next(g)) # 调用__next__()方法运行至 yield 处,返回yield 后面的值。等待下一次调用。
print(next(g)) # 从yield 处继续运行,直到遇到下一个yield,返回 yield 后的值,等待下一次next调用。
print(g.send('qianlei')) # send()方法传入的参数会被 res 接收,其他和 next()相同。send(None) == next()
可迭代对象 iterable
迭代器 iterator
生成器 generator
生成器 属于 迭代器,迭代器 属于 可迭代对象。
生成器列表生成式使用()圆括号,或者函数定义中使用yeild
迭代器,使用next()或者__next__(),每次只能取出一个值,节省内存。
可迭代对象,可以使用for循环的都是可迭代对象,使用iter() iter() 可以转换为迭代器。如列表字典等。
可迭代对象一般有具体范围,便于操作。迭代器一般是数据流,没有具体范围。