从类中创建全局变量(来自字符串)

时间:2012-11-09 15:33:55

标签: python python-2.7

背景:我正在制作一个Ren'py游戏。值为Character()。是的,我知道在这种背景之外这是一个愚蠢的想法。

我需要从类范围之外的类中的输入字符串创建变量:

class Test:
    def __init__(self):
        self.dict = {} # used elsewhere to give the inputs for the function below.

    def create_global_var(self, variable, value):
        # the equivalent of exec("global {0}; {0} = {1}".format(str(variable), str(value)))
        # other functions in the class that require this.

Test().create_global_var("abc", "123") # hence abc = 123

我已尝试过vars()[]globals()[variable] = value等,但他们根本无法工作(他们甚至没有定义任何内容)编辑:这是我的问题。< / p>

我知道以下内容同样适用,但我希望变量在正确的范围内:

setattr(self.__class__, variable, value) # d.abc = 123, now. but incorrect scope.

如何在类中使用字符串作为变量名在全局范围内创建变量,而不在python中使用属性或exec?

是的,我会进行健全检查。

2 个答案:

答案 0 :(得分:6)

首先要做的事情:我们称之为Python的“全局”范围实际上是“模块”范围 (从好的方面来说,它减少了使用全球变量的“邪恶”)。

然后,为了动态创建一个全局var,虽然我仍然不明白为什么会这样 比使用模块级字典更好,只需:

globals()[variable] = value

这会在当前模块中创建一个变量。如果需要在调用方法的模块上创建模块变量,可以使用以下方法从调用者框架中查看全局字典:

from inspect import currentframe
currentframe(1).f_globals[variable] = name

现在,这似乎特别无用,因为您可以使用动态名称创建变量,但不能动态访问它(除非再次使用全局字典)

即使在您的测试示例中,您创建了传递方法字符串的“abc”变量,但是您必须使用硬编码的“abc”来访问它 - 语言本身旨在阻止这种情况(因此不同于Javascript,其中数组索引和对象属性是可互换的,而在Python中你有distinc Mapping对象)

我的建议是你使用模块级显式字典并创建你的所有字典 动态变量作为键/值对:

names = {}
class Test(object):
    def __init__(self):
        self.dict = {} # used elsewhere to give the inputs for the function below.

    def create_global_var(self, variable, value):
         names[variable] = value

(旁注,在Pyhton 2中总是从“对象”继承你的类)

答案 1 :(得分:2)

您可以使用setattr(__builtins__, 'abc', '123')

请注意,这很可能是设计问题,您应该重新考虑设计。