在Python中声明一个全局动态变量

8

我是一名Python/编程新手,也许我的问题根本没有意义。

我的问题是如果变量是动态的,我无法将其设置为全局变量,我的意思是我可以这样做:

def creatingShotInstance():

    import movieClass

    BrokenCristals = movieClass.shot()
    global BrokenCristals #here I declare BrokenCristals like a global variable and it works, I have access to this variable (that is a  shot class instance) from any part of my script.
    BrokenCristals.set_name('BrokenCristals')
    BrokenCristals.set_description('Both characters goes through a big glass\nand break it')
    BrokenCristals.set_length(500)
    Fight._shots.append(BrokenCristals)

def accesingShotInstance():
    import movieClass

    return BrokenCristals.get_name()#it returns me 'BrokenCristals'

但是,如果我声明一个字符串变量,像这样:

def creatingShotInstance():

    import movieClass

    a = 'BrokenCristals'

    vars()[a] = movieClass.shot()
    global a #this line is the only line that is not working now, I do not have acces to BrokenCristals class instance from other method, but I do have in the same method.
    eval(a+".set_name('"+a+"')")
    eval(a+".set_description('Both characters goes through a big glass\nand break it')")
    eval(a+".set_length(500)")
    Fight._shots.append(vars()[a])

def accesingShotInstance():
    import movieClass

    return BrokenCristals.get_name()#it returns me 'BrokenCristals is not defined'

我尝试了这个:

global vars()[a]

并且这个:

global eval(a)

但是它给我一个错误。我该怎么办?


6
听取提示,不要这样做。从长远来看,拥有一个“动态”变量是没有意义的。你甚至为什么想要这样一个东西呢? - S.Lott
aaronasterling 不是一个玩笑(无论如何感谢您的好评论),我试图做的是创建一个类示例,并使用来自 UI 条目的名称作为动态变量。 - user497457
1
那么,Ned Batchelder已经为您解决了这个问题。除非您想要一个准花哨的元类,根据电影名称注册实例并提供实现享元模式的构造函数。Ned的解决方案几乎肯定更好。 - aaronasterling
记住,global a 处理名为 'a' 的全局变量;如果你知道我是什么意思(不是全局是一个函数 - global(a) 不会起作用),则 global a 变成了 global('a') - Chris Morgan
如果变量,包括其名称本身都是动态的,你如何把它硬编码到函数中?如果要为此使用全局变量,请给它一个不变的全局名称,并将其作为容器对象(如字典或类实例)存储任何需要的数据。顺便说一下,文档建议不要修改vars()返回的字典。 - martineau
4个回答

19

为了完整起见,这是你原问题的答案。但几乎肯定不是你想要做的--很少有情况下修改作用域的 dict 是正确的做法。

globals()[a] = 'whatever'

1
抱歉,似乎不起作用了...我仍然得到这个消息:名称 'BrokenCristal' 未定义。 - user497457
在Python 2.7中,这对我实际上并没有起作用。它似乎修改了全局变量,但是当我离开作用域时,全局变量会恢复到先前的状态。 - Translunar
谢谢,它实际上适用于Python 2.7.17,至少我可以pickle和unpickle一个在其他模块中动态创建的namedtuple(并将其添加到全局变量中)。 - Yaroslav Nikitenko

8

不要使用动态全局变量,而应该使用字典:

movies = {}

a = 'BrokenCristals'

movies[a] = movieClass.shot()
movies[a].set_name(a)
# etc

抱歉,但我仍然遇到同样的问题。当我尝试从任何其他方法获取BrokenCristals shot类实例的值时,我会收到此消息:名称“BrokenCristals”未定义...有什么想法吗? - user497457
尝试使用 movies['BrokenCristals'].get_name(),例如。你没有一个名为 BrokenCristals 的变量。你有一个键为 'BrokenCristals' 的字典名为 movies - Ned Batchelder
非常感谢您的回答和对像我这样的新手的耐心指导 :-D - user497457

2

0

你的代码运行良好!

只是一个拼写错误和缺少括号!

第一个语法错误是没有方括号:

  File "main.py", line 6
    global BrokenCristals
    ^
SyntaxError: name 'BrokenCristals' is assigned to before global declaration

第二个语法错误:global后面没有字母s。

  File "main.py", line 6
    global [BrokenCristals]
           ^
SyntaxError: invalid syntax

修正后的语法:

def creatingShotInstance():

    import movieClass

    BrokenCristals = movieClass.shot()
    globals [BrokenCristals]
    BrokenCristals.set_name('BrokenCristals')
    BrokenCristals.set_description('Both characters goes through a big glass\nand break it')
    BrokenCristals.set_length(500)
    Fight._shots.append(BrokenCristals)

def accesingShotInstance():
    import movieClass

    return BrokenCristals.get_name()

使用已声明字符串修正语法:

def creatingShotInstance():

    import movieClass

    a = 'BrokenCristals'

    vars()[a] = movieClass.shot()
    globals [a] 
    eval(a+".set_name('"+a+"')")
    eval(a+".set_description('Both characters goes through a big glass\nand break it')")
    eval(a+".set_length(500)")
    Fight._shots.append(vars()[a])

def accesingShotInstance():
    import movieClass

    return BrokenCristals.get_name()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接