2012-10-09 84 views
2

说我有一个类:动态实例属性

class Foo(object): 
    def __init__(self,d): 
     self.d=d 

d={'a':1,'b':2} 

inst=Foo(d) 

inst.d 
Out[315]: {'a': 1, 'b': 2} 

有没有一种方法来dyamically创建n个属性,每个属性是一个字典键,所以inst.a将返回1等。

+1

是的,但你不能使用它们,因为'inst.0'是非法语法。 – nneonneo

+2

是的,但为什么你会这样做,而不是通过索引访问项目,无论是直接从列表中,或通过覆盖['__getitem__'和朋友](http://docs.python.org/py3k/reference/datamodel.html #模拟容器类型)。 – delnan

+0

@ nneonneo - 编辑了这个问题。 – root

回答

2

使用setattr()

>>> class foo(object): 
    def __init__(self, d): 
     self.d = d 
     for x in self.d: 
      setattr(self, x, self.d[x]) 


>>> d = {'a': 1, 'b': 2} 
>>> l = foo(d) 
>>> l.d 
{'a': 1, 'b': 2} 
>>> l.a 
1 
>>> l.b 
2 
>>> 
+0

@root是的,只需在'__init __()'内部移动for-loop即可。 –

3
class Foo(object): 
    def __init__(self, attributes): 
     self.__dict__.update(attributes) 

这样做。

>>>foo = Foo({'a': 42, 'b': 999}) 
>>>foo.a 
42 
>>>foo.b 
999 

您还可以使用setattr内置方法:

class Foo(object): 
    def __init__(self, attributes): 
     for attr, value in attributes.iteritems(): 
      setattr(self, attr, value) 
+0

虽然它会工作,但setattr是正确的方法。 – Krumelur

1

这里是比pythonm提供了一个解决方案更加古怪:

class Foo(object): 
    def __init__(self, d): 
     self.__dict__ = d 

而不是使用inst.d,直接使用inst.__dict__。另外一个好处是添加到d的新密钥会自动成为属性。这就像动态一样。

0

你可以做这样的事情:

class Foo(object): 
    def __init__(self, **kwdargs): 
     self.__dict__.update(kwdargs) 

d = {'a':1,'b':2} 

foo = Foo(**d) 
foo2 = Foo(a=1, b=2) 
0

您还可以使用__getattr__

class Foo(object): 

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

    def __getattr__(self, name): 
     return self.d[name]