Class 从字典创建类实例属性?
我正在从CSV导入数据,并以大致相同的格式获取数据Class 从字典创建类实例属性?,class,python,komodo,Class,Python,Komodo,我正在从CSV导入数据,并以大致相同的格式获取数据 { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 } 字段的名称是动态的。(好吧,它们是动态的,因为可能不止有Field1和Field2,但我知道Field1和Field2总是会存在 我希望能够将这本词典传入我的类allMyFields,这样我就可以作为属性访问上述数据 class allMyFields: # I think I need to include thes
{ '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树吗?您可以使用(但要小心:不是每个字符串都是有效的属性名!):
编辑:让我解释一下上述代码与的区别。上面的代码片段创建了一个类,其实例属性基于给定的字典。SilentGhost的代码创建了一个类,其类属性基于给定的字典
根据您的具体情况,这两种解决方案中的任何一种都可能更合适。您希望创建一个或多个类实例吗?如果答案是一个,您最好完全跳过对象创建,只构造类型(因此使用SilentGhost的答案)
文档很好地解释了这里发生了什么(请参阅用作构造函数)
编辑:如果需要实例变量,以下操作也可以:
>>> a = q() # first instance
>>> a.Field1
3000
>>> a.Field1 = 1
>>> a.Field1
1
>>> q().Field1 # second instance
3000
您还可以使用
dict.update
而不是手动循环项
(如果您正在循环,iteritems
更好)
使用setattr实现漂亮的方式。quick-n-dirty方式是更新实例内部字典:
>>> class A(object):
... pass
...
>>> a = A()
>>> a.__dict__.update({"foo": 1, "bar": 2})
>>> a.foo
1
>>> a.bar
2
>>>
使用命名元组(Python 2.6):
您可以创建一个子类
dict
,该子类允许键的属性查找:
class AttributeDict(dict):
def __getattr__(self, name):
return self[name]
q = AttributeDict({ 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 })
print q.Field1
print q.Field2
print q.RandomField
如果您试图查找dict
已经具有的属性(例如keys
或get
),您将获得该dict
类属性(一种方法)。如果您请求的密钥在dict
类中不存在,则将调用\uuu getattr\uuuu
方法并执行密钥查找。或者您可以尝试此操作
class SomeClass:
def __init__(self,
property1,
property2):
self.property1 = property1
self.property2 = property2
property_dict = {'property1': 'value1',
'property2': 'value2'}
sc = SomeClass(**property_dict)
print(sc.__dict__)
class AllMyFields:
def __init__(self, field1, field2, random_field):
self.field1 = field1
self.field2 = field2
self.random_field = random_field
@classmethod
def get_instance(cls, d: dict):
return cls(**d)
a = AllMyFields.get_instance({'field1': 3000, 'field2': 6000, 'random_field': 5000})
print(a.field1)
增强的
重复dict工作
类属性指令(dict):
"""https://stackoverflow.com/a/1639632/6494418"""
def _ugetattr _;(self,name):
如果不存在,则返回self[name](self[name],dict)\
else属性指令(self[名称])
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
d={“你好”:1,“世界”:2,“猫”:{“狗”:5}
d=属性指令(d)
打印(d.cat)
打印(d.猫狗)
打印(d.cat.items())
"""
{'dog':5}
5.
口述项目([('dog',5)])
"""
< /代码> 如果你想添加一个新的库,PyDyTic是一个非常有效的解决方案。它使用Python注释来构造对象和验证类型,考虑下面的代码:
from pydantic import BaseModel
class Person(BaseModel):
name: str
age: str
data = {"name": "ahmed", "age": 36}
p = Person(**data)
pydantic:+1,但我认为你应该解释一下这段代码的作用,或者提供文档的链接。我猜他的名字是“SilentGhost”方法很简洁,但它们是类变量这一事实没有实例变量那么引人注目。如果需要,您可以实例化q
。Komodo编辑提示不需要类属性。它可以读取\uuuu init\uuuu
方法体来查找self.
变量。更根本的是,您为什么不使用简单的de>csv.DictReader
用于此操作并从每行创建字典?SLott-I使用re.sub()手动修改标题并添加一个“假”标题。这不是一个很好的理由,但在DictReader之后重命名密钥要昂贵得多。带有额外编辑的代码解释了两个好答案之间的差异,非常有用,谢谢!我惊喜地发现此解决方案与form_dict=flask.form.to_dict()一起使用从一个长web表单创建一个db.Model实例。太棒了!注意-表单中输入的整数和浮点数以字符串的形式返回,但在类使用之前很容易修复。如果键中有空格,是否有简单的修复方法?例如:instance。由于空格的原因,其他一些东西
无法工作。我想知道是否有一个优雅的解决方法。@Jarad使用map(lambda-kv:[kv[0])替换(''''.''.'),kv[1]),dictionary.items())
,而不仅仅是dictionary
。这将用下划线替换所有键名中的所有空格。
class AttributeDict(dict):
def __getattr__(self, name):
return self[name]
q = AttributeDict({ 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 })
print q.Field1
print q.Field2
print q.RandomField
class SomeClass:
def __init__(self,
property1,
property2):
self.property1 = property1
self.property2 = property2
property_dict = {'property1': 'value1',
'property2': 'value2'}
sc = SomeClass(**property_dict)
print(sc.__dict__)
class AllMyFields:
def __init__(self, field1, field2, random_field):
self.field1 = field1
self.field2 = field2
self.random_field = random_field
@classmethod
def get_instance(cls, d: dict):
return cls(**d)
a = AllMyFields.get_instance({'field1': 3000, 'field2': 6000, 'random_field': 5000})
print(a.field1)
from pydantic import BaseModel
class Person(BaseModel):
name: str
age: str
data = {"name": "ahmed", "age": 36}
p = Person(**data)