关于局部变量的作用域问题
def outside():var = 5
def inside():
print(var)
var = 3 #但是令人非常不解的是,把这句话删了,就不会报错,就可以访问外部变量了,输出值是5
inside()
outside()
这个会报错 说我没有定义var
我的困惑是 print(var)比var = 3率先执行,此时为什么不能去访问外部变量呢,打印5,而是报错呢? 哎,你在打印 var 变量时,它以为是要打印外层的那个 var,
可你在后面又定义了 var ,就屏蔽了它, 上面那条语句自然也就不知到该输出哪个 var 了! 因为你在函数里面对这个变量赋值的话,它就把这个变量当成了局部变量,
所以在这个变量定义之前使用就会报错了,你如果希望不把它当成局部变量的话,就加个 nonlocal 声明
def outside():
var = 5
def inside():
nonlocal var
print(var)
var = 3
inside()
outside()
python爱好者. 发表于 2022-3-12 19:44
哎,你在打印 var 变量时,它以为是要打印外层的那个 var,
可你在后面又定义了 var ,就屏蔽了它, 上面 ...
但是var是在print后面定义的 print不应该先执行吗 所以我的理解是print执行的时候不知道我后面定义了var? 看你的代码出错的地方应该是var=3这一句,出错的原因是修改局部变量的值。默认情况下Python不允许在函数内修改全局变量的值,函数内定义的子函数也不允许修改外部函数的局部变量。print(var)这一句是可以运行的,因为它只是访问了局部变量var的值而没有修改它,但是var=3这一句就是在修改局部变量var的值了,这种行为违反了语法所以报错。
你可以这样修改inside这个函数
def inside():
nonlocal var
print(var)
var = 3
所以概括来说就是如果不用global或者nonlocal关键字声明,则只能在函数内访问全局变量或局部变量的值,但是不能修改它们的值。
更多例子:
# 全局变量
var = 'hello'
# 访问但不修改
def access_global():
print(var)
# 错误修改全局变量
de wrong_modify_global():
var = 10# 报错
print(var)
# 正确修改全局变量
def right_modify_global():
global var# 声明var为全局变量,不是局部变量
var = 10
print(var)
# 访问局部变量
def access_local():
var = 233
def inside():
print(var)# 只访问但不修改
inside()
# 正确修改局部变量
def right_modify_local():
var = 233
def inside():
nonlocal var# 声明var为局部变量
var = 666
print(var)
inside()
Jerry~Mouse 发表于 2022-3-12 19:55
但是var是在print后面定义的 print不应该先执行吗 所以我的理解是print执行的时候不知道我后面定义了var ...
嗯
python爱好者. 发表于 2022-3-12 20:05
嗯
啊?既然改变变量的操作在后面执行 那就不应该报错啊 我执行print的时候 var = 3 这条语句还没有开始执行 所以应该打印5 为啥报错呢 isdkz 发表于 2022-3-12 19:46
因为你在函数里面对这个变量赋值的话,它就把这个变量当成了局部变量,
所以在这个变量定义之前使用就会 ...
改变变量的操作在后面执行 那就不应该报错啊 我执行print(var)的时候 var = 3 这条语句还没有开始执行 所以应该采用外部变量 打印5 但是为啥报错呢 Jerry~Mouse 发表于 2022-3-12 22:23
改变变量的操作在后面执行 那就不应该报错啊 我执行print(var)的时候 var = 3 这条语句还没有开始执行...
因为变量要讲"自由"啊,哈哈
当你 将var=3,写在print(var)之后,var就不再是"自由变量",就无法"向外找/向上找"了。
当然即使你将var=3写在print(var)之前,它也不是"自由变量",而是"本地变量/局部变量"。
总之,你可以看做赋值等号=,是一种约束,一旦你进行了赋值,它就失去了"自由",就无法再"向上找"了。
^_ 阿奇_o 发表于 2022-3-13 00:57
因为变量要讲"自由"啊,哈哈
当你 将var=3,写在print(var)之后,var就不再是"自由变量",就无法" ...
那在print的时候 还没有执行到var = 3 这条语句 所以print那条语句中的var应该还是自由的? 本帖最后由 阿奇_o 于 2022-3-13 15:57 编辑
Jerry~Mouse 发表于 2022-3-13 13:07
那在print的时候 还没有执行到var = 3 这条语句 所以print那条语句中的var应该还是自由的?
这里的"自由",不是从表面的语句执行顺序来考虑的,而是从它能否"向外找"来判断。
"自由变量"这个概念不完全是你想的那样。具体定义你自己搜吧。 反正,语法规则它不允许你这样操作。
你可以多查查资料,再试试不同的情况,应该可以理解。
页:
[1]