python中的全局变量警告[重复]

时间:2021-10-26 23:13:48

This question already has an answer here:

这个问题在这里已有答案:

I have a python 2.6 script (yes I know I should upgrade to at least 2.7) that looks like this:

我有一个python 2.6脚本(是的,我知道我应该升级到至少2.7),看起来像这样:

ret_code = 0

def some_func()
  global ret_code
  ...

if __name__ == '__main__':
  global ret_code
  ...

Now I get a warning if I run the code: *SyntaxWarning: name 'ret_code' is assigned to before global declaration global ret_code*

现在,如果我运行代码,我会收到警告:*语法警告:名称'ret_code'在全局声明全局ret_code之前分配给*

Why do I get this warning?

为什么我会收到这个警告?

I can solve the problem by doing so:

我这样做可以解决问题:

def some_func()
      global ret_code
      ...

if __name__ == '__main__':
  global ret_code
  ret_code = 0 #assign 0 here instead of above
  ...

Still that doesn't answer my question. What is wrong with the original code?

仍然没有回答我的问题。原始代码有什么问题?

1 个解决方案

#1


74  

The best direct way to fix this is to remove the global declaration from underneath if __name__ == '__main__':. You don't need it there. Unlike some other languages, an if statement doesn't introduce a new scope in Python - any variables you assign in that block are global, just as they would be without the if there.

解决此问题的最佳直接方法是,如果__name__ =='__ main__',则从下面删除全局声明:你不需要那里。与其他一些语言不同,if语句不会在Python中引入新的作用域 - 您在该块中分配的任何变量都是全局的,就像它们没有if那样。

This also explains why it is an error: to declare a variable as global, you are not allowed to have used that variable name previously in the same scope (presumably because it would be confusing for the global statement to make assignments before it go to the global variable, and Python doesn't support the same name being both global and local in the same scope). Since the if doesn't introduce a new scope, the first assignment to ret_code is in the same scope as the global declaration under the if; but the global declaration comes later than the assignment, which isn't allowed.

这也解释了为什么它是一个错误:将变量声明为全局变量,不允许以前在同一范围内使用该变量名称(可能是因为全局语句在进入之前进行赋值会令人困惑。全局变量,并且Python不支持在同一范围内同名全局和本地)。由于if不引入新范围,因此ret_code的第一个赋值与if下的全局声明的范围相同;但是全局声明比赋值更晚,这是不允许的。

For an even better fix, consider if you can remove the mutable global state from your program entirely, since it usually causes more problems than its worth somewhere down the track. Here, it seems likely that you're using ret_code as a program exit code - ie, you'll be doing sys.exit(ret_code) somewhere - but you're deciding inside a function which exit code to use. Instead, pass enough information back out to the top level code for it to decide which exit code to use.

为了获得更好的解决方案,请考虑是否可以完全从程序中删除可变全局状态,因为它通常会导致更多问题,而不是它在某个地方的价值。在这里,您似乎可能使用ret_code作为程序退出代码 - 也就是说,您将在某处执行sys.exit(ret_code) - 但是您正在决定使用退出代码的函数内部。相反,将足够的信息传递回*代码,以决定使用哪个退出代码。

#1


74  

The best direct way to fix this is to remove the global declaration from underneath if __name__ == '__main__':. You don't need it there. Unlike some other languages, an if statement doesn't introduce a new scope in Python - any variables you assign in that block are global, just as they would be without the if there.

解决此问题的最佳直接方法是,如果__name__ =='__ main__',则从下面删除全局声明:你不需要那里。与其他一些语言不同,if语句不会在Python中引入新的作用域 - 您在该块中分配的任何变量都是全局的,就像它们没有if那样。

This also explains why it is an error: to declare a variable as global, you are not allowed to have used that variable name previously in the same scope (presumably because it would be confusing for the global statement to make assignments before it go to the global variable, and Python doesn't support the same name being both global and local in the same scope). Since the if doesn't introduce a new scope, the first assignment to ret_code is in the same scope as the global declaration under the if; but the global declaration comes later than the assignment, which isn't allowed.

这也解释了为什么它是一个错误:将变量声明为全局变量,不允许以前在同一范围内使用该变量名称(可能是因为全局语句在进入之前进行赋值会令人困惑。全局变量,并且Python不支持在同一范围内同名全局和本地)。由于if不引入新范围,因此ret_code的第一个赋值与if下的全局声明的范围相同;但是全局声明比赋值更晚,这是不允许的。

For an even better fix, consider if you can remove the mutable global state from your program entirely, since it usually causes more problems than its worth somewhere down the track. Here, it seems likely that you're using ret_code as a program exit code - ie, you'll be doing sys.exit(ret_code) somewhere - but you're deciding inside a function which exit code to use. Instead, pass enough information back out to the top level code for it to decide which exit code to use.

为了获得更好的解决方案,请考虑是否可以完全从程序中删除可变全局状态,因为它通常会导致更多问题,而不是它在某个地方的价值。在这里,您似乎可能使用ret_code作为程序退出代码 - 也就是说,您将在某处执行sys.exit(ret_code) - 但是您正在决定使用退出代码的函数内部。相反,将足够的信息传递回*代码,以决定使用哪个退出代码。