名称空间
又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方
名称空间共3种,分别如下
- locals: 是函数内的名称空间,包括局部变量和形参
- globals: 全局变量,函数定义所在模块的名字空间
- builtins: 内置模块的名字空间
不同变量的作用域不同就是由这个变量所在的命名空间决定的。
作用域即范围
- 全局范围:全局存活,全局有效
- 局部范围:临时存活,局部有效
查看作用域方法 globals(),locals()
装饰器
user_status = False #用户登录了就把这个改成True def login(func):#把要执行模块从这里传进来 def inner(*args,**kwargs):#再定义一成函数 _username = 'albert' # 假装这是DB里存的用户信息 _password = 'abc123' # 假装这是DB里存的用户信息 global user_status if user_status == False: username = input('username:') password = input('password:') if username == _username and password == _password: print('Welcome login...') user_status = True else: print('wrong username or password') if user_status == True: func(*args,**kwargs) # 只要验证通过了,就调用功能 return inner #用户调用login时,只会返回inner的内存地址,下次再调用时加上()才会执行inner函数 def home(): print('----首页----') @login #america = login(america) def america(): #login()执行前加上验证 print('----欧美专区----') def japan(style): print('----日韩专区----',style) #@login def henan(style): # login()执行前加上验证 print('----河南专区----',style) home() #america = login(america) #inner america('sad') #login(america) #需要验证就调用 login,把需要验证的功能,当做一个参数传给login japan('gh') henan = login(henan) choose = input('choose:') henan(choose) 接下来是加上qq或其他方式登录
user_status = False def login(auth_type): def outer(func): def inner(*arg,**kwargs): _username = 'albert' _password = 'abc123' global user_status if user_status == False: username = input('username:') password = input('password:') if username == _username and password == _password: print('welcome login...') user_status = True else: print('wrong username or password!') else: print('用户已登录,验证通过...') if user_status == True: # 等同于 if user_status: func() func(*arg,**kwargs) return inner return outer def home(): print("---------首页---------") @login('qq') def ameriaca(style): print("---------欧美---------",style) def japan(): print("---------日韩---------") @login('wx') def henan(style): print("---------河南---------",style) home() ameriaca('3p') japan() henan('3p')
作用域查找顺序
level = 'L0'
n = 22
def func():
level = 'L1'
n = 33
print(locals())
def outer():
n = 44
level = 'L2'
print(locals(),n)
def inner():
level = 'L3'
print(locals(),n) #此外打印的n是多少?
inner()
outer()
func()
问题:在inner()里的打印的n的值是多少?
LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
- locals 是函数内的名字空间,包括局部变量和形参
- enclosing 外部嵌套函数的名字空间
- globals 全局变量,函数定义所在模块的名字空间
- builtins 内置模块的名字空间
闭包
关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响。
def outer():
name = 'alex'
def inner():
print("在inner里打印外层函数的变量",name)
return inner
f = outer()
f()
闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域