马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
×
本帖最后由 15271953841 于 2024-3-3 13:21 编辑
Python 3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
一、 作用域scope:指一个变量可以被访问的范围
(一)局部作用域:如果一个变量定义的位置是在一个函数的里面,那么它的作用域仅限于该函数中,我们将它称为局部变量。
def myfunc():
x=520
print(x)
myfunc()
520
print(x)
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
print(x)
NameError: name 'x' is not defined (报错原因:如果尝试在函数的外部去访问这个局部变量,会报错)
(二)全局作用域:如果是在任何函数的外面去定义一个变量,那它的作用域是全局的,我们也将其称为全局变量。
x=880
def myfunc():
print(x)
myfunc()
880
def myfunc():
x=520
print(x)
myfunc()
520 (在函数中,局部变量会覆盖同名的全局变量)
print(x) (所以我们在调用myfunc()函数时,它打印的是局部变量x的值,但是只要出了函数,由于作用域的关系,局部变量就失效了,因此打印的是全局变量的x的值。)
880
x=880
id(x)
2237598375504
def myfunc():
print(id(x))
myfunc()
2237598375504 (在函数中,如果没有同名的局部变量覆盖的话,它打印的就是)
def myfunc():
x=520 (多了一个同名的局部变量x=520,去覆盖全局变量x=880,但它不可能把外面的全局变量x=880的值修改掉)
print(id(x))
myfunc()
2237598381712
结论:全局变量可以在函数内部访问到,但是却无法在函数中去修改它的值,因为你一旦试图对它进行赋值操作,Python就会立即创建一个同名的局部变量进行覆盖,Python这种保护表现给容易出现bug的操作增加困难。
二、globab语句
x=880
def myfunc():
global x (用global声明x是一个全局变量,现在要修改函数体外的这个全局变量)
x=520 (用局部变量去修改全局变量)
def myfunc():
global x
x=520
print(x)
myfunc()
520
print(x)
520
三、嵌套函数
def funA():
x=520
def funB():
x=880
print("In funB,x=",x)
print("In funA,x=",x)
funB() (在外部,调用funB(),它会报错,)
Traceback (most recent call last):
File "<pyshell#45>", line 1, in <module>
funB() (报错原因:说找不到这玩意)
NameError: name 'funB' is not defined. Did you mean: 'funA'?
def funA():
x=520
def funB():
x=880
print("In funB,x=",x)
funB() (要想调用funB(),只能通过外部函数funA函数来调用,在定义的时候就要调用funB)
print("In funA,x=",x)
funA()
In funB,x= 880
In funA,x= 520
四、nonlocal语句
def funA():
x=520
def funB():
nonlocal x (声明修改上一层嵌套的函数变量)
x=880
print("In funB,x=",x)
funB()
print("In funA,x=",x)
funA()
In funB,x= 880
In funA,x= 880
五、LEGB规则——Python变量解析机制
Local局部作用域
Enclosed嵌套函数的外层函数作用域
Global是全局作用域
Build-In内置作用域
前三个已经演示,当局部作用域与全局作用域发生冲突的时候,Python会使用局部作用域的变量,除非你使用Global语句进行特别的声明。
当函数嵌套发生的时候,局部作用域又会覆盖外层函数的作用域,除非你使用nonlocal()语句进行申明。
最后一个是B,就是Build-In,是最没有地位的那个。
str="小姐姐把str给毁了"
str(520)
Traceback (most recent call last):
File "<pyshell#53>", line 1, in <module>
str(520)
TypeError: 'str' object is not callable (报错原因:是str函数的作用就将一个类型转换成字符串的类型,原因我们前面将str作为一个变量名赋值给了一个字符串,这时str已经变成了一个全局变量)
Str (这时str已经变成了一个全局变量,而不是Build-In,根据LEGB的法则,G比B要高,所以当它们出现冲突的时候,G就毫不留情的把B给覆盖了,所以str这个BIF(build-In function)内置函数就被毁掉了。)
'小姐姐把str给毁了'
|