Python中的作⽤域及global⽤法
Python 中,⼀个变量的作⽤域总是由在代码中被赋值的地⽅所决定的。
1、函数定义了本地作⽤域,⽽模块定义的是全局作⽤域。如果想要在函数内定义全局作⽤域,需要加上global修饰符。
2、变量名解析:LEGB原则
当在函数中使⽤未认证的变量名时,Python搜索4个作⽤域:
①本地作⽤域(L)(函数内部声明但没有使⽤global的变量)
②之后是上⼀层结构中def或者lambda的本地作⽤域(E)
③之后是全局作⽤域(G)(函数中使⽤global声明的变量或在模块层声明的变量)
④最后是内置作⽤域(B)(即python的内置类和函数等)
如果在第⼀处能够到这个变量名,那么python此时会停⽌查。如果变量名在整个的搜索过程中都没有到,Python就会报错。
补充:上⾯的变量规则只适⽤于简单对象,当出现引⽤对象的属性时,则有另⼀套搜索规则:属性引⽤搜索⼀个或多个对象,⽽不是作⽤域,并且有可能涉及到所谓的"继承"
3、global修饰符的⽤法:
①⾸先是python的⼀个奇异现象,在模块层⾯定义的变量(⽆需global修饰),如果在函数中没有再定义同名变量,可以在函数中当做全局变量使⽤:
hehe=6
def f():
print(hehe)
f()
print(hehe)
上述代码可以正常运⾏且输出为6和6
python中lambda怎么使用
②但如果在函数中有再赋值/定义(因为python是弱类型语⾔,赋值语句和其定义变量的语句⼀样),则
会产⽣引⽤了未定义变量的错误:hehe=6
def f():
print(hehe)
hehe=2
f()
print(hehe)
抛出的错误信息为:
UnboundLocalError: local variable 'hehe' referenced before assignment
③⽽如果在函数中的定义在引⽤前使⽤,那么会正常运⾏但函数中的变量和模块中定义的全局变量不为同⼀个
hehe=6
def f():
hehe=2
print(hehe)
f()
print(hehe)
上述输出是2和6,也即f函数中print使⽤的是局部变量hehe,⽽最后⼀个print语句使⽤的全局hehe。
④那么我们会有疑问,如果我可能在函数使⽤某⼀变量后⼜对其进⾏修改(也即再赋值),怎么让函数⾥⾯使⽤的变量是模块层定义的那个全局变量⽽不是函数内部的局部变量呢?这时候global修饰符就派上⽤场了。
hehe=6
def f():
global hehe
print(hehe)
hehe=3
f()
print(hehe)
在⽤global修饰符声明hehe是全局变量的hehe后(注意,global语句不允许同时进⾏赋值如global hehe=3是不允许的),上述输出是6和3,得到了我们想要的效果。