Use*_*ser 5 python global-variables dynamic variable-assignment
我是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"
Run Code Online (Sandbox Code Playgroud)
这就是问题.我该如何解决?
你的问题是Python的工作方式不符合你的想法.
因此,我将尝试逐行解释代码中发生的情况.
mouse = "a"
Run Code Online (Sandbox Code Playgroud)
将字符串"a"分配给名称mouse.
background = "b"
Run Code Online (Sandbox Code Playgroud)
将字符串"b"分配给名称background.
list_ab = [mouse, background]
Run Code Online (Sandbox Code Playgroud)
将名称mouse和引用的两个对象分配background给列表list_ab.
我们已经知道,它们是常数"a"和"b".所以你可以写:
list_ab = ["a", "b"]
Run Code Online (Sandbox Code Playgroud)
现在循环
for item in list_ab:
Run Code Online (Sandbox Code Playgroud)
将列表中的每个对象分配给名称item.
对于第一次循环迭代,它意味着item = "a".
这条线
global item # I want to modify the GLOBAL item, which is mouse ad background
Run Code Online (Sandbox Code Playgroud)
没有意义,因为它试图告诉Python该名称item是全局的,而没有声明这样的全局变量.
而对于最令人困惑的行为
item = "modified"
Run Code Online (Sandbox Code Playgroud)
你应该明白的是,虽然它分配"修改"的名称字符串item,字符串"A"和"B"仍然是相同的,并且仍然被分配到列表中list_ab(和名称mouse,并background,你也不要触摸).
名称item本身仅存在于声明的范围内,当"for"循环结束时,它被破坏.它也会在每次迭代时重新分配给下一个项目list_ab.
把它们加起来:
如果要将"已修改"字符串分配给列表中的项目,请直接执行:
list_ab[0] = "modified"
list_ab[1] = "modified"
Run Code Online (Sandbox Code Playgroud)
如果需要更改全局范围中声明的变量,请执行以下操作:
mouse = "a"
def func():
global mouse # tell Python that you want to work with global variable
mouse = "modified"
func()
print mouse # now mouse is "modified"
Run Code Online (Sandbox Code Playgroud)
基于问题第一次修订的示例:
代替
background = g_base("bg.jpg") # g_base class instance
mouse = g_base("mouse.png",alpha=1) # g_base class instance
imgs_to_load = [mouse, background]
def Image_loader (img):
# ..... code to load the image and convert it into pygame surface...
return img_load
def main ():
for image in img_to_load:
global image
image = Image_loader (img)
print image # if I print image, it is a pygame surface
print background # But here, outside the loop, image is still a g_base instance ?!?!
print mouse # " "
main()
Run Code Online (Sandbox Code Playgroud)
你可以做:
imgs_to_load = [g_base("bg.jpg"), g_base("mouse.png",alpha=1)] # list with a g_base class instances
def Image_loader(img):
# ..... code to load the image and convert it into pygame surface...
return img_load
def main ():
imgs_in_pygame_format = [] # create an empty list
for image in imgs_to_load:
loaded_image = Image_loader(image)
imgs_in_pygame_format.append(loaded_image) # add to the list
for image in imgs_in_pygame_format:
print image # every image in the list is a pygame surface
# or
print image[0]
print image[1]
main()
Run Code Online (Sandbox Code Playgroud)
或者,如果要按名称引用图像,可以将它们放入字典中:
imgs_to_load = {}
imgs_to_load["bg"] = g_base("bg.jpg")
imgs_to_load["mouse"] = g_base("mouse.png",alpha=1)
imgs_in_pygame_format = {} # create a global dictionary for loaded images
def main ():
global imgs_in_pygame_format # import that global name into the local scope for write access
for name, data in imgs_to_load.items():
imgs_in_pygame_format[name] = Image_loader(data) # add to the dictionary
for image in imgs_in_pygame_format:
print image # every image in the dictionary is a pygame surface
# or
print imgs_in_pygame_format["bg"]
print imgs_in_pygame_format["mouse"]
main()
Run Code Online (Sandbox Code Playgroud)
但最重要的是,全局变量是个坏主意.更好的解决方案是使用一个类:
def Image_loader(img):
# ..... code to load the image and convert it into pygame surface...
return img_load
class Image:
def __init__(self, image):
self.data = Image_loader(image)
def main ():
bg = Image(g_base("bg.jpg"))
mouse = Image(g_base("mouse.png",alpha=1))
print bg.data
print mouse.data
main()
Run Code Online (Sandbox Code Playgroud)
有关更多示例,请参阅Python教程.
希望它有所帮助,欢迎来到StackOverflow!
正如我在对您的问题的评论中所说,list_ab不包含对mouse和 的引用background。在这种情况下,您可以通过将他们的名字放在列表中来在某种程度上模拟,如下所示:
mouse = "a"
background = "b"
list_ab = ['mouse', 'background']
def func():
for name in list_ab:
globals()[name] = "modified"
print mouse # must be "modified" not "a"
print background # must be "modified" not "b"
func()
# modified
# modified
Run Code Online (Sandbox Code Playgroud)
globals()返回一个类似字典的对象,该对象表示脚本/模块执行中那个点的非本地名称绑定。重要的是要注意 中list_ab的for循环不会改变它func()。此外,您应该知道,这只是使您的示例代码按您想要的方式工作的一种简单方法的说明,而不是完成这些事情的特别好的或通用的方法。