类和功能范围

时间:2014-12-05 18:41:55

标签: python function class oop instance

我想从用户输入的字符串创建类的实例,所以我使用了exec()函数。问题是我无法通过函数外部的名称访问实例。我的第一个想法是,它是一个函数范围的问题,我仍然认为它是,但当我将实例放入列表时,我可以访问它们,只是不使用它们的名称。我不确定这里发生了什么..有没有办法让我可以通过他们的名字访问实例,比如thing1.properties但是在函数之外,因为这不是我的整个代码所以它会很混乱把所有功能都放在外面?类似于在函数中创建实例列表以及提取"函数外的所有实例,所以我可以在函数外部访问它们。这是代码:

class Things:
    def __init__(self, properties):
        self.properties = properties

listt = []
def create_instance():
    exec("thing1=Things('good')")
    listt.append(thing1)

create_instance()
print listt[0].properties
print thing1.properties

1 个答案:

答案 0 :(得分:1)

虽然我厌恶污染全局命名空间,但exec语句可以将第二个参数用作范围,默认为locals()

>>> def foo(name):
...     exec "{} = 1".format(name)
... 
>>> def bar(name):
...     exec "{} = 1".format(name) in globals()
... 
>>> foo('a')
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> bar('a')
>>> a
1

因此,如果您通过globals作为范围,它将按您的意愿工作,但是真的吗?对全局范围进行自我污染是非常可怕的,在评估用户提供的代码时这样做是一种该死的责任。

[更新]

  

非常有帮助!谢谢!但现在更好的方法是做什么,字典还是全球范围?

也许您可以将所有实例存储到类变量中,例如:

class Thing(object):
    instances = {}
    def __init__(self, name, **properties):
        self.name = name
        self.properties = properties
        self.instances[name] = self
    def __repr__(self):
        t = '<"{self.name}" thing, {self.properties}>'
        return t.format(self=self)

现在你可以做到:

# declare your things
>>> Thing('foo', a=1, b=2)
>>> Thing('bar', a=3, b=4)

# retrieve them by name
>>> Thing.instances.get('foo')
<"foo" thing, {'a': 1, 'b': 2}>

>>> Thing.instances.get('foo').properties
{'a': 1, 'b': 2}

>>> Thing.instances.get('bar').properties
{'a': 3, 'b': 4}