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

Ame*_*lia 3 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
Run Code Online (Sandbox Code Playgroud)

我试过vars()[],globals()[variable] = value等等,他们根本不工作(他们甚至没有定义任何东西)编辑:这是我的问题.

我知道以下内容同样可以正常工作,但我希望变量在正确的范围内:

setattr(self.__class__, variable, value) # d.abc = 123, now. but incorrect scope.
Run Code Online (Sandbox Code Playgroud)

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

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

jsb*_*eno 6

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

然后,为了动态创建全局变量,虽然我仍然看不出为什么这比使用模块级字典更好,但是只需:

globals()[variable] = value
Run Code Online (Sandbox Code Playgroud)

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

from inspect import currentframe
currentframe(1).f_globals[variable] = name
Run Code Online (Sandbox Code Playgroud)

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

即使在您的测试示例中,您创建了传递方法字符串的"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
Run Code Online (Sandbox Code Playgroud)

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