F1r*_*yte 7 python python-3.x python-3.5 python-3.6
我一直试图理解为什么python会以这种方式运行,在下面的代码块中.我做了我的研究,但找不到一个好的答案所以我来到这里看看是否有人可以指出我正确的方向或提供一个很好的澄清.我知道它与一些旧的ALGOL原理有关,但我不完全理解它.
var = 5
def func1():
print(var)
func1()
def func2():
var = 8
print(var)
func2()
def func3():
print(var)
var = 8
func3()
Run Code Online (Sandbox Code Playgroud)
此代码的输出如下:
5
8
UnboundLocalError:赋值前引用的局部变量'var'
我理解为什么我们得到输出'5'和'8'.但是使用'func3()',我期待输出'5'.看起来,解释器认为我想在函数中打印局部'var'而不是全局'var'.所以它抛出了这个错误.
或者,如果在函数内部的某处定义了变量,则该函数将默认为局部变量,而不是具有相同名称的全局变量.
但是为什么python会这样表现呢?我不抱怨,我只是想了解一些事情......
我如何在函数中使用预定义的全局变量,然后在同一函数内定义一个具有相同名称的局部变量,而不更改全局变量的值?(当然是在python中)
在此先感谢大家.你是个很棒的人!:)
Edit_1:感谢每一个人给出了很好的答案.我完全理解在函数中使用预定义的全局变量是一个坏的和不切实际的想法,然后在同一个函数内定义一个具有相同名称的局部变量.我只是从理论的角度思考它,因为我在大学讲座中看到过它.XD我找不到一个用例,在这个用例中最好也是这样!
Edit_2:我已经阅读了PEP8,我知道明确比隐含更好.:) 这是真的.否则代码会混淆并导致错误.那个问题只是我试图理解的一些无用且不切实际的大学理论.
Edit_3:现在我完全理解为什么会发生这种情况以及这里发生了什么.感谢Randall Valenciano将这个链接提供给一个能够很好地解释它的博客.
会发生什么是该函数被解释为一个整体,而不是一行一行.因此,在解释函数时,任何已定义变量的变量声明都会移动到函数的顶部.因此,当我们打印'var'时,该函数正在使用本地声明的变量,该变量尚未分配任何值,然后解释器会抱怨它并抛出错误.
再次感谢大家!:)你对我有很大的帮助!现在我终于明白了幕后发生了什么.
r.o*_*ook 12
您var被定义为全局变量.在每个函数中,当你只是在阅读var你正在访问的全局变量时,但是var当函数中的某个地方有一个赋值时,python会将函数中的每一个都 var视为局部变量.这就是为什么你的最后一个函数失败了,因为print(var)(之前的本地变量)被调用了var = 8.
您可以在这些线程中阅读更多内容:
外部作用域中定义的阴影名称有多糟糕?
Python非本地语句
最好的做法是明确你的代码,如果你试图引用一个本地,非本地或全局变量,它就不再混淆了.
在这种情况下,假设您打算继续使用全局变量,请执行以下操作:
var = 5
def func1():
print(var)
func1()
def func2():
global var
var = 8
print(var)
func2()
def func3():
global var
print(var)
var = 8 # technically this is not necessary any more var = 8 was already assigned when func2() is called
func3()
Run Code Online (Sandbox Code Playgroud)
因此输出:
5
8
8
Run Code Online (Sandbox Code Playgroud)
编辑:感谢juanpa.arrivillaga的评论 - 我错过了你原来的问题.
我如何在函数中使用预定义的全局变量,然后在同一函数内定义一个具有相同名称的局部变量,而不更改全局变量的值?(当然是在python中)
简短的回答是 - var像你一样定义当地的第一个func2()并且你很好.更长的答案是 - 你为什么要那样做?它会造成混乱,并且在跟踪不同范围内具有相同名称的变量时会变得很头疼.一个更好的方法是将您的本地local_var变量命名为或者某种东西,以便它明显不同并且易于跟踪.
小智 5
这个答案是Python范围解析的规则
LEGB规则.
L,Local - 在函数内以任何方式分配的名称(def或lambda)),并且在该函数中未声明为全局.
E,Enclosing-function locals - 从内到外的任何和所有静态封闭函数(def或lambda)的局部范围中的名称.
G,全局(模块) - 在模块文件的顶层分配的名称,或通过在文件中的def中执行全局语句.
B,内置(Python) - 在内置名称模块中预先分配的名称:open,range,SyntaxError,...
因此,基本上在您的问题中,范围解析是"从内到外",并且由于您没有使用global关键字,因此解释器不知道在本地函数范围之外查找该变量var.所有解释器都看到你在声明和定义变量之前使用变量,从而抛出错误.全局变量通常很危险,因此Python希望通过强制您明确它来确保您知道要使用全局变量.
希望能帮助到你.
| 归档时间: |
|
| 查看次数: |
223 次 |
| 最近记录: |