动态全局变量赋值

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)

这就是问题.我该如何解决?

kol*_*bos 6

你的问题是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!


mar*_*eau 5

正如我在对您的问题的评论中所说,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_abfor循环不会改变它func()。此外,您应该知道,这只是使您的示例代码按您想要的方式工作的一种简单方法的说明,而不是完成这些事情的特别好的或通用的方法。