从字典创建类实例属性?
我正在从一个CSV文件导入数据,得到的数据大致是这样的格式:
{ 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
字段的名称是动态的。也就是说,可能会有比Field1
和Field2
更多的字段,但我知道Field1
和Field2
总是会存在。
我希望能把这个字典传入我的类allMyFields
,这样我就可以像访问属性一样访问上面的数据。
class allMyFields:
# I think I need to include these to allow hinting in Komodo. I think.
self.Field1 = None
self.Field2 = None
def __init__(self,dictionary):
for k,v in dictionary.items():
self.k = v
#of course, this doesn't work. I've ended up doing this instead
#self.data[k] = v
#but it's not the way I want to access the data.
q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
instance = allMyFields(q)
# Ideally I could do this.
print q.Field1
有什么建议吗?我想这样做的原因是我想利用代码提示,而像我现在这样把数据导入到一个叫data
的字典中并不能让我享受到这个功能。
(因为变量名在运行时才会被解析,所以我还是得给Komodo一些提示,我觉得self.Field1 = None
应该就足够了。)
那么,我该怎么做才能实现我的想法呢?还是说我在追求一个设计不好的、与Python不太相符的方案?
12 个回答
20
你也可以用 dict.update
来代替手动一个一个遍历 items
(如果你真的要遍历的话,使用 iteritems
会更好)。
class allMyFields(object):
# note: you cannot (and don't have to) use self here
Field1 = None
Field2 = None
def __init__(self, dictionary):
self.__dict__.update(dictionary)
q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
instance = allMyFields(q)
print instance.Field1 # => 3000
print instance.Field2 # => 6000
print instance.RandomField # => 5000
43
>>> q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
>>> q = type('allMyFields', (object,), q)
>>> q.Field1
3000
关于 type
的文档解释得很清楚,这里讲的是它的用法(可以当作构造函数来用)。
补充说明: 如果你需要实例变量,下面的代码也可以用:
>>> a = q() # first instance
>>> a.Field1
3000
>>> a.Field1 = 1
>>> a.Field1
1
>>> q().Field1 # second instance
3000
151
你可以使用setattr
这个函数(不过要小心:不是每个字符串都能作为有效的属性名!):
>>> class AllMyFields:
... def __init__(self, dictionary):
... for k, v in dictionary.items():
... setattr(self, k, v)
...
>>> o = AllMyFields({'a': 1, 'b': 2})
>>> o.a
1
补充说明:让我来解释一下上面的代码和SilentGhost的回答之间的区别。上面的代码片段创建了一个类,这个类的实例属性是基于给定的字典。而SilentGhost的代码则创建了一个类,这个类的类属性是基于给定的字典。
根据你的具体情况,这两种解决方案可能各有适用之处。你是打算创建一个类的实例,还是多个实例?如果答案是一个,那你可以完全跳过对象的创建,直接构造类型(这样就可以选择SilentGhost的回答)。