命名空间和作用域
作用域,就是 python 程序中,可以直接访问命名空间的正文区域。
python 中程序的变量也是有作用范围的,在范围之外是不能访问的,能访问的范围决定于变量定义/赋值的位置。
局部作用域(Local,最内层,函数或闭包函数内,包含局部变量)
闭包函数外的作用域(Enclosing),主要就是嵌套函数中闭包函数外的区域,包含非局部(non-local)也非全局(non-global的变量)
全局作用域(glocal),当前程序的最外层区域,包含本程序文件/模块的全局变量
内建作用域(built-in)包含了内建函数、关键字等。在使用一个变量的时候,会按照由内而外的顺序取寻找该变量的定义,内层可屏蔽外层
num1=123 #全局作用域变量
def fun():
num1=234 # 闭包函数外的函数中变量
def fun1():
num1=345 #局部作用域变量
python 中只有模块(module)、类(class)以及函数(def、lambda)能引入新的作用域
其他语句块是不会引入新的作用域的,如 if…else… 、try…except…和 for/while等
def fun():
inner=21
list1=[1,2,3,4]
a='abcdef'
for i in list1:
a+=a[i]
print(i) #这里是可以使用i的,因为i在for中定义了,for不形成新作用域
print(a)
# print(inner) #这里会报错,因为inner只在函数fun中定义了,在函数外没定义,所以找不到inner变量
global 和 nonlocal 关键字
global 用在局部作用域或闭包函数外的函数作用域中,用来指出在该作用域中使用的变量是全局变量,而非局部变量,该变量可以是在全局作用域中出现过的变量,也可以是没出现过的变量。
但是必须在第一次使用之前声明,否则就会报错
num = 0 # 这是一个全局变量
def fun1():
num =2
# global num # 函数内,在global声明之前已经使用过num.这里会报错
print ("函数内: ", num)
return num
fun1()
print ("函数外: ", num)
nonlocal 用在闭包函数内的函数作用域中,用来指出在该作用域中使用的同名变量不是局部变量,而是一个外部变量,注意,
若闭包函数外的函数中没有此同名变量则会报错
num = 0 # 这是一个全局变量
def fun1():
# global num
num = 1 # num 在这里是全局变量.
def fun2():
nonlocal num # 这里会报错,因为在外层函数中没有同名局部变量;注释掉global num就不会报错了
num=2
print("闭包函数内: ", num)
return num
fun2()
print ("函数内: ", num)
return num
fun1()
print ("函数外: ", num)
缘由
不可变类型
总的来说对于不可变类型:像 int 、 float 、 str 等类型;
定义即赋值,修改实际上是新的定义,这一类变量的定义和修改都是使用赋值运算符 '='。
可变类型
像 list 、 set 、 dict 等类型是一类可变类型,所谓可变类型,就是定义之后,还可以对变量进行修改,修改前后,
该变量的 id 不变,这一类变量定义使用赋值运算符,
修改则需要下标(或键),还可以有插入、删除等操作。
list1=['a','b','c']
def fun1():
# global list1
list1[0]='f' #这里已经使用过全局变量了,在函数内就不能再定义同名的局部变量了
print('fun1内,打算定义一个与全局变量同名的局部变量:')
"""
若这一行没有注释掉#global list1就不会报错
缘由是在同一个作用域中被定义了全局变量,此时是全局变量被赋值,修改
"""
# list1=['s'] #这里定义同名的变量,会报错;
def fun2():
print('fun2内,打算定义一个与全局变量同名的局部变量:')
list1=[123,'abc'] #这里定义了一个与全局变量同名的局部变量
list1.append('123') #这里使用的也是局部变量
print('fun2函数内:',list1)
fun1()
print('执行fun1之后,函数外:',list1)
fun2()
print('执行fun2之后,函数外:',list1)
参考Python细节之7、global与nonlocal的使用
之前也写过,但不详细global与nonlocal
努力拼搏吧,不要害怕,不要去规划,不要迷茫。但你一定要在路上一直的走下去,尽管可能停滞不前,但也要走。