为什么python认为这是一个局部变量?

时间:2022-12-17 16:49:06

I have a global variable I called Y_VAL which is initialized to a value of 2.

我有一个名为Y_VAL的全局变量,它被初始化为值2。

I then have a function, called f() (for brevity), which uses Y_VAL.

然后我有一个函数,称为f()(为了简洁),它使用Y_VAL。

def f():
    y = Y_VAL
    Y_VAL += 2

However, when trying to run my code, python gives the error message:

但是,在尝试运行我的代码时,python会给出错误消息:

UnboundLocalError: local variable 'Y_VAL' referenced before assignment

If I remove the last line Y_VAL += 2 it works fine.

如果我删除最后一行Y_VAL + = 2,它可以正常工作。

Why does python think that Y_VAL is a local variable?

为什么python认为Y_VAL是局部变量?

3 个解决方案

#1


14  

You're missing the line global Y_VAL inside the function.

你错过了函数内的全局Y_VAL行。

When Y_VAL occurs on the right-hand-side of an assignment, it's no problem because the local scope is searched first, then the global scope is searched. However, on the left-hand-side, you can only assign to a global that way when you've explicitly declared global Y_VAL.

当Y_VAL出现在赋值的右侧时,没有问题,因为首先搜索局部范围,然后搜索全局范围。但是,在左侧,只有在明确声明全局Y_VAL时才能以全局方式分配。

From the docs:

来自文档:

It would be impossible to assign to a global variable without global, although free variables may refer to globals without being declared global.

没有全局变量就不可能分配给全局变量,尽管*变量可以引用全局变量而不被声明为全局变量。

#2


1  

This is just how Python works: Assignment always binds the left-hand side name in the closest surrounding name space. Inside of a function the closest namespace is the local namespace of the function.

这就是Python的工作原理:赋值总是绑定最近的名称空间中的左侧名称。在函数内部,最近的命名空间是函数的本地命名空间。

In order to assign to a global variable, you have to declare it global. But avoid global by all means. Global variables are almost always bad design, and thus the use of the global keyword is a strong hint, that you are making design mistakes.

要分配给全局变量,必须将其声明为全局变量。但是一定要避免全球化。全局变量几乎总是糟糕的设计,因此使用global关键字是一个强烈的暗示,即你正在犯设计错误。

#3


0  

I ran to the same issue as you and as many others like you, before realising it needs the global statement. I then decided to move everything to object orientation and have piece of mind. Call me insane but I just dont trust myself with the global statement and its not difficult to come against a problem of local scope that is a pain to debug.

在遇到需要全局声明之前,我遇到了和你以及许多其他人一样的问题。然后,我决定将所有东西都移到面向对象的位置,并且有一点心思。叫我疯了,但我不相信自己的全局声明,并且不难发现本地范围的问题,这是一个很难调试。

So I would advice collect all your "global" variables put them in a class inside an init(self) and not only you wont have to worry about local scope but you will have your code much better organised. Its not a freak of luck that most programmer out there prefer OOP.

所以我建议收集你所有的“全局”变量,将它们放在init(self)中的一个类中,不仅你不必担心局部范围,而且你的代码组织得更好。它不是一个运气怪,大多数程序员都喜欢OOP。

#1


14  

You're missing the line global Y_VAL inside the function.

你错过了函数内的全局Y_VAL行。

When Y_VAL occurs on the right-hand-side of an assignment, it's no problem because the local scope is searched first, then the global scope is searched. However, on the left-hand-side, you can only assign to a global that way when you've explicitly declared global Y_VAL.

当Y_VAL出现在赋值的右侧时,没有问题,因为首先搜索局部范围,然后搜索全局范围。但是,在左侧,只有在明确声明全局Y_VAL时才能以全局方式分配。

From the docs:

来自文档:

It would be impossible to assign to a global variable without global, although free variables may refer to globals without being declared global.

没有全局变量就不可能分配给全局变量,尽管*变量可以引用全局变量而不被声明为全局变量。

#2


1  

This is just how Python works: Assignment always binds the left-hand side name in the closest surrounding name space. Inside of a function the closest namespace is the local namespace of the function.

这就是Python的工作原理:赋值总是绑定最近的名称空间中的左侧名称。在函数内部,最近的命名空间是函数的本地命名空间。

In order to assign to a global variable, you have to declare it global. But avoid global by all means. Global variables are almost always bad design, and thus the use of the global keyword is a strong hint, that you are making design mistakes.

要分配给全局变量,必须将其声明为全局变量。但是一定要避免全球化。全局变量几乎总是糟糕的设计,因此使用global关键字是一个强烈的暗示,即你正在犯设计错误。

#3


0  

I ran to the same issue as you and as many others like you, before realising it needs the global statement. I then decided to move everything to object orientation and have piece of mind. Call me insane but I just dont trust myself with the global statement and its not difficult to come against a problem of local scope that is a pain to debug.

在遇到需要全局声明之前,我遇到了和你以及许多其他人一样的问题。然后,我决定将所有东西都移到面向对象的位置,并且有一点心思。叫我疯了,但我不相信自己的全局声明,并且不难发现本地范围的问题,这是一个很难调试。

So I would advice collect all your "global" variables put them in a class inside an init(self) and not only you wont have to worry about local scope but you will have your code much better organised. Its not a freak of luck that most programmer out there prefer OOP.

所以我建议收集你所有的“全局”变量,将它们放在init(self)中的一个类中,不仅你不必担心局部范围,而且你的代码组织得更好。它不是一个运气怪,大多数程序员都喜欢OOP。