嘿,我刚开始对这个问题感到疑惑,因为我遇到了一个代码,它预期某个对象具有一定的属性集(但没有说明该对象应该是什么类型)。
一种解决方案是创建一个具有代码所需属性的新类,但是当我调用其他需要具有(其他)属性的对象的代码时,我必须创建越来越多的类。
更简短的解决方案是创建一个泛型类,然后在它的实例上设置属性(对于那些想要使用object
实例而不是创建新类的人来说,这是不可行的object
个实例不允许新属性。)
我提出的最后一个最短的解决方案是创建一个带有构造函数的类,它接受关键字参数,就像dict
构造函数一样,然后将它们设置为属性:
class data:
def __init__(self, **kw):
for name in kw:
setattr(self, name, kw[name])
options = data(do_good_stuff=True, do_bad_stuff=False)
但我不禁觉得我错过了一些明显的东西......是不是有内置的方法来做到这一点(最好在Python 2.5中支持)?
答案 0 :(得分:22)
使用__dict__
:
In [1]: class data:
...: def __init__(self, **kwargs):
...: self.__dict__.update(kwargs)
...:
In [2]: d = data(foo=1, bar=2)
In [3]: d.foo
Out[3]: 1
In [4]: d.bar
Out[4]: 2
答案 1 :(得分:22)
type('', (), {})()
将创建一个可以具有任意属性的对象。
示例:
obj = type('', (), {})()
obj.hello = "hello"
obj.world = "world"
print obj.hello, obj.world #will print "hello world"
带有三个参数的 type()
会创建一个新类型。
第一个参数''
是新类型的名称。我们不关心这个名字,所以我们把它留空了。
第二个参数()
是基类型的元组,这里是object
(隐式)。
第三个参数是新对象的属性字典 - 我们再也不关心它是一个空字典{}
最后,我们在最后用()
实例化这个新类型的新实例。
答案 2 :(得分:16)
使用collections.namedtuple
。
效果很好。
from collections import namedtuple
Data = namedtuple( 'Data', [ 'do_good_stuff', 'do_bad_stuff' ] )
options = Data( True, False )
答案 3 :(得分:13)
这适用于2.5,2.6和3.1:
class Struct(object):
pass
something = Struct()
something.awesome = abs
result = something.awesome(-42)
编辑: 我想也许给消息来源也会有所帮助。 http://docs.python.org/tutorial/classes.html#odds-and-ends
编辑: 添加了对结果的分配,因为我使用交互式解释器来验证,而您可能不是。
答案 4 :(得分:10)
这是我所知道的最短路
>>> obj = type("myobj",(object,),dict(foo=1,bar=2))
>>> obj.foo
1
>>> obj.bar
2
>>>
使用dict代替{}确保您的属性名称有效
>>> obj = type("myobj",(object,),{"foo-attr":1,"bar-attr":2})
>>> obj.foo-attr
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'myobj' has no attribute 'foo'
>>>
答案 5 :(得分:6)
使用lambda和type build-in之间的组合,我认为这是最小的方法:
obj = lambda **kwargs: type('obj', (object,), kwargs)()
options = obj(do_good_stuff=True, do_bad_stuff=False)
print options.do_good_stuff
print options.do_bad_stuff
答案 6 :(得分:4)
如果您不需要在构造函数中传递值,则可以执行以下操作:
class data: pass
data.foo = 1
data.bar = 2
使用类静态成员变量来保存数据。
答案 7 :(得分:0)
如果我理解你的问题,你需要记录。 Python类可以这样使用,这就是你所做的。
我相信处理“记录”的最pythonic方式就是...... 词典!类是类固醇的一种字典。
您的类示例data
本质上是一种将字典转换为类的方法。
(旁注,我宁愿使用self.__setattr__(name, kw[name])
。)
答案 8 :(得分:0)
您可能对“Struct”感兴趣,它是IPython包的一部分。它通过许多有用的方法做你想做的事。
http://ipython.org/ipython-doc/rel-0.13/api/generated/IPython.utils.ipstruct.html
答案 9 :(得分:0)
这通常是你要使用dict的东西,而不是根本不用。