动态全局变量赋值
我是 python 新手,在使用 global
指令时遇到很多麻烦。
这是一个代码示例:
mouse = "a"
background = "b"
list_ab = [mouse, background]
def func ():
for item in list_ab:
global item # I want to modify the GLOBAL item, which is mouse
# and background.
item = "modified"
print mouse # must be "modified" not "a"
print background # must be "modified" not "b"
这就是问题所在。我该如何解决?
I'm new in python and I'm having many troubles in using global
instruction.
Here is a code example:
mouse = "a"
background = "b"
list_ab = [mouse, background]
def func ():
for item in list_ab:
global item # I want to modify the GLOBAL item, which is mouse
# and background.
item = "modified"
print mouse # must be "modified" not "a"
print background # must be "modified" not "b"
This is the problem. How can I solve it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您的问题是 Python 的工作方式与您想象的不同。
因此,我将尝试逐行解释代码中发生的情况。
将字符串“a”分配给名称
mouse
。将字符串“b”分配给名称
background
。将名称为
mouse
和background
引用的两个对象分配给列表list_ab
。我们已经知道,它们是常数“a”和“b”。所以你可以这样写:
现在循环将
列表中的每个对象分配给名称
item
。对于第一次循环迭代,它意味着
item = "a"
。该行
没有意义,因为它试图告诉 Python 名称
item
是全局的,但没有声明这样的全局变量。对于线上最令人困惑的行为,
您应该明白,虽然它将字符串“modified”分配给名称
item
,但字符串“a”和“b”仍然相同,并且仍然被分配到列表list_ab
(以及名称mouse
和background
,您也没有碰过它们)。名称
item
本身仅存在于声明它的范围内,当“for”循环结束时,它就会被破坏。每次迭代时,它也会被重新分配给
list_ab
中的下一个项目。总结一下:
如果您想将“modified”字符串分配给列表中的项目,请直接执行:
如果您需要更改在全局范围内声明的变量,请执行以下操作:
基于问题第一次修订的示例:
而不是
您可以这样做:
或者如果您想按名称引用图像,您可以将它们放入字典中:
但最重要的是,全局变量是个坏主意。更好的解决方案是使用类:
有关更多示例,请参阅 Python 教程。
希望它对您有所帮助,欢迎来到 StackOverflow!
Your problem is that Python works not the way you think.
So I will try to explain what's going on in your code, line by line.
Assigns the string "a" to the name
mouse
.Assigns the string "b" to the name
background
.Assigns two objects, referenced by names
mouse
andbackground
, to the listlist_ab
.As we already know, they are constants "a" and "b". So you can just write:
Now the loop
assigns each object in the list to the name
item
.For the first loop iteration, it means
item = "a"
.The line
doesn't make sense, because it tries to tell Python that the name
item
is global, while there is no such global variable declared.And for the most confusing behavior on the line
you should just understand that while it assigns the string "modified" to the name
item
, strings "a" and "b" are still the same, and still assigned to the listlist_ab
(and namesmouse
andbackground
, which you didn't touch either).The name
item
itself lives only in the scope where it was declared, when the "for" loop ends, it's destructed.It is also reassigned every iteration with the next item from the
list_ab
.To sum it up:
If you want to assign "modified" string to the items in the list, do it directly:
If you need to change variable declared in the global scope, do this:
Example based on the first revision of the question:
Instead of
You can do:
Or if you want to reference to images by name, you can put them into dictionary:
But most importantly, global variables are bad idea. The better solution would be to use a class:
For more examples see Python Tutorial.
Hope it helps, and welcome to StackOverflow!
正如我在对您的问题的评论中所说,
list_ab
不包含对mouse
和background
的引用。在这种情况下,您可以通过将它们的名称放入列表中来在某种程度上进行模拟,如下所示:globals()
返回类似字典的内容代表脚本/模块执行中该时刻的非本地名称绑定的对象。需要注意的是,list_ab
不会被func()
中的for
循环更改。此外,您还应该意识到,这只是使示例代码按您想要的方式工作的一种简单方法的说明,而不是完成此类事情的特别好的或通用的方法。As I said in my comment to your question,
list_ab
does not contain references tomouse
andbackground
. You can simulate that to some degree in this case by putting their names in the list, like this:globals()
returns a dictionary-like object that represents the non-local name bindings at that point in your script/modules's execution. It's important to note thatlist_ab
is not changed by thefor
loop infunc()
. Also you should be aware that this is only an illustration of one simple way to make your sample code work like you wanted, not of an especially good or generic way to accomplish such things.我不确定你想做什么。
global
关键字旨在将全局名称导入到当前作用域中,而不是使本地名称成为全局名称。I am not sure what you are trying do to. The
global
keyword is intended to import a global name into the current scope, not to make a local name global.您遇到两个不同的问题,其中之一出现两次。第一个是您尝试在列表的元素上使用
global
,这是无用的。您已经可以这样做:这将更改
list_ab
引用的值,该值比您的代码现在获得的更远。它之所以有效,是因为您没有更改list_ab
表示的绑定,因此它不需要是全局的。您已经可以读取全局索引,并且它只是一个项目查找,并且(本身)不会覆盖任何绑定。然而,它实际上不会改变a
和b
引用的值第二个是当您将
list_ab
的第一个和第二个索引绑定到a
和b
,它创建全新的绑定,因此更改列表中绑定的值不会更改a
引用的值和b。如果你想这样做,你需要直接这样做。当您尝试通过迭代来修改
list_ab
的元素时,您会再次遇到第二个问题。您可以通过代码更清楚地看到它。再次,出现这种情况是因为您正在创建一个到该值的新绑定,然后修改该绑定而不是原始绑定。
如果您需要在迭代列表时就地修改列表,您可以执行以下
操作,因此目前的情况是更新
a
、b
和list_ab
,并保持当前的模式(即不引入推导式),您需要这样做:这看起来很丑陋。为什么需要将它们保留为自由变量并保存在列表中?仅仅列出一个清单还不够吗?如果您需要按名称访问它们,则可以使用字典:
You are having two distinct problems and one of them occurs twice. The first is that you are attempting to use
global
on elements of a list which is useless. You can already do:This will change the values which are referenced by
list_ab
which is further than your code is getting now. It works because you are not changing the binding represented bylist_ab
and so it doesn't need to be global. You can already read a global indexing and into it is just an item lookup and doesn't (in itself) overwrite any bindings. However it will not actually change which values are referenced bya
andb
The second is that when you bind the first and second indices of
list_ab
toa
andb
, it creates entirely new bindings so that changing the values of the bindings in the list does nothing to change the values referenced bya
andb
. If you want to do that, you need to do it directly.You are running into the second problem again when you try to modify the elements of
list_ab
by iterating over them. You can see it more clearly with the codeAgain, this occurs because you are creating a new binding to the value and then modifying that binding instead of the original one.
If you need to modify a list in place while iterating over it you can do
So as things currently stand to update
a
,b
andlist_ab
, and keeping your current patterns (i.e. not introducing comprehensions), you need to do:That looks pretty ugly. Why do you need to keep them as free variables and in a list? Isn't just a list good enough? If you need to access them by name then you can use a dictionary:
这里的问题是您试图就地更新变量,但您的函数返回新实例。尝试这样的事情:
如果你想特别简洁,这里有一个单行代码可以做同样的事情:
但实际上,如果你只有两个图像,那么明确地这样做可能更有意义:
The issue here is that you're trying to update variables in-place, but your functions return new instances. Try something like this:
And if you want to be especially concise, here's a one-liner that does the same thing:
But really, if you only have two images, it might make more sense to do this explicitly:
我也不确定你想做什么,但这里有一个使用
global
的示例:I'm not sure what you are trying to do either, but here's an example of using
global
: