在Python中将动态变量分配给字典

时间:2014-11-18 23:34:58

标签: python

我试图执行以下操作:

class DoSomething:
   def something(self, number, name)
      self.main_dict = {}
      setattr(self,name,['anything'])
      self.main_dict[number] = getattr(self,name) 

以上将属性(按值引用)传递给字典。不是我需要的行为。

我想将动态变量的引用传递给字典,而不是属性。 继续我修改动态变量,我希望它反映在字典中。

有可能这样做吗?


编辑:

为什么?

1)学习如何做这样的事情,并在工具箱中再添一个工具。 提供的答案涉及使用"参考/容器" class并为每个所需的值创建一个实例。完美。

2)因为这个问题是由另一个可解决的问题造成的(最初没有看到)。注意我进一步修改动态创建的变量。为此,需要通过(setattr, vars, __dict__, etc)动态调用它。它没有被修改,它被分配了一个新的值来改变引用,而不是反映到dict。

我想指出有关赋值/引用的内容: How do I pass a variable by reference?

3)意图是维护。通过在dict-variable的开头引用,程序员就会知道对变量所做的任何更改都会反映到字典中。

4)我在关于使用lambda的评论中提到过。这只有在name永远不会被修改的情况下才有效,否则lambda会将最后指定的值用于name

3 个答案:

答案 0 :(得分:0)

我认为你正在寻找这样的东西:

class DoSomething(object):
   def something(self, number, name):
      self.main_dict = {}
      setattr(self, name, ['anything'])
      setattr(self, number, getattr(self, name))

setattr可以设置名称由name值指定的属性。 getattr将返回其名称由number的值指定的属性的值。

作为上述使用的一个例子:

In [33]: s = DoSomething()

In [34]: s.something('x', 'alpha')

In [35]: s.x
Out[35]: ['anything']

In [36]: s.alpha
Out[36]: ['anything']

答案 1 :(得分:0)

Yes. This will work.

但是,动态设置类的属性并不是一个好主意,因为很难跟踪可用的内容和不依赖于实例化或访问对象的时间。

class Thing(object):
   def setP(self,name,value):
       setattr(self,name,value)
   def getP(self,name):
       return getattr(self,name)

foo = Thing()
foo.setP('bar','baz')
print foo.bar

给出:

> baz

然而,课程的一个优点是(理想情况下)它提出了关于公共成员和职能的公共合同。如果你不能合理地确定一个对象将有一个在任何给定时间的属性,或同一类的两个实例将不具有相同的属性 - (所有归功于furkle)

在上面的代码中,这不起作用:

foo = Thing()
print foo.bar

并且会引发异常,因此删除类外部的一行已经调用访问对象属性失败。

同样地:

foo = Thing()
goh = Thing()
foo.setP('bar','baz')
print foo.bar
print goh.bar

这也会引发异常。动态地将属性分配给obejcts使得很难知道某些对象何时可用。

答案 2 :(得分:-1)

您可以通过定义包含所需值的可变对象来完成此操作。类dict和main_dict指向此对象,它包含一个可以动态更改的值。

class DynValue(object):

    __slots__ = 'val'

    def __init__(self, val):
        self.val = val

    def __str__(self):
        return str(self.val)

    def __repr__(self):
        return 'DynValue{%s}' % repo(self.val)



class DoSomething:
    def something(self, number, name):
        self.main_dict = {}
        val = DynValue(['anything'])
        setattr(self,name,val)
        self.main_dict[number] = val

    def sometimelater(self, name):
        getattr(self, name).val = ['somethingelse']


d=DoSomething()
d.something(1, 'fred')
print d.main_dict[1]
d.sometimelater('fred')
print d.main_dict[1]

让一个容器保存该值并让其他容器引用它也很常见。因此,如果您将值直接存储在self上,则会将名称存储在main_dict中并每次都进行查找。

class DoSomething:
   def something(self, number, name)
      self.main_dict = {}
      setattr(self,name,['anything'])
      self.main_dict[number] = name

   def get_by_number(self, number):
      return getattr(self, self.main_dict[number])

   def set_by_number(self, number, newval):
      setattr(self, self.main_dict[number], newval)

   def set_by_name(self, name newval):
      setattr(self, name, newval)