在python中,如何将类对象强制转换为dict
假设我有一个简单的python类在python中,如何将类对象强制转换为dict,python,Python,假设我有一个简单的python类 class Wharrgarbl(object): def __init__(self, a, b, c, sum, version='old'): self.a = a self.b = b self.c = c self.sum = 6 self.version = version def __int__(self): return self.s
class Wharrgarbl(object):
def __init__(self, a, b, c, sum, version='old'):
self.a = a
self.b = b
self.c = c
self.sum = 6
self.version = version
def __int__(self):
return self.sum + 9000
def __what_goes_here__(self):
return {'a': self.a, 'b': self.b, 'c': self.c}
我可以很容易地把它转换成整数
>>> w = Wharrgarbl('one', 'two', 'three', 6)
>>> int(w)
9006
太棒了!但是,现在我想以类似的方式把它交给一个dict
>>> w = Wharrgarbl('one', 'two', 'three', 6)
>>> dict(w)
{'a': 'one', 'c': 'three', 'b': 'two'}
我需要定义什么才能让它工作?我尝试用\u dict\u
和dict
替换\u这里的内容,但是dict(w)
导致了类型错误:Wharrgarbl对象在这两种情况下都不适用。我不认为简单地让课堂变得易学就能解决问题。我还尝试了许多谷歌搜索,其中包含了我所能想到的“python将对象转换为dict”的不同措辞,但找不到任何相关内容:{
另外!请注意调用w.\uu dict\uuu
不会做我想做的事情,因为它将包含w.version
和w.sum
。我想通过使用def int(self)
将强制转换自定义为int
,以同样的方式将强制转换自定义为int
我知道我可以这样做
>>> w.__what_goes_here__()
{'a': 'one', 'c': 'three', 'b': 'two'}
但是我假设有一种pythonic方法可以使dict(w)
工作,因为它与int(w)
或str(w)是同一类型的东西
。如果没有更具python风格的方法,那也没关系,我想我会问。哦!我想,既然这很重要,这是针对python2.7的,但对于一个2.4年前就已经过时的解决方案来说,这也是一个额外的积分
还有一个问题与此类似,但可能不同到足以证明这不是一个重复的问题。我相信OP正在询问如何将其类对象中的所有数据转换为字典。我正在寻找一种更为定制的方法,因为我不希望字典返回中包含\uu dict\uu
中的所有内容由dict()
编辑。类似于公共变量和私有变量的内容可能足以解释我要查找的内容。对象将存储计算中使用的一些值,这样我就不需要/不想显示在结果字典中
更新:
我选择了asdict建议的路线,但选择我想要的答案是一个艰难的选择。@RickTeachey和@jpmc26都提供了我将要使用的答案,但前者有更多的信息和选项,也得到了相同的结果,而且被投票率更高,所以我选择了。Upal谢谢你的帮助。我已经在stackoverflow上埋伏了很长时间,我正努力让自己的脚趾更多地伸进水里。如果不知道问题的全部背景,很难说,但我不会忽略\uuuuuiter\uucode>
class MyKwargUnpackable:
def keys(self):
return list("abc")
def __getitem__(self, key):
return dict(zip("abc", "one two three".split()))[key]
我将在类上实现\uu此处的内容\uuu
as_dict(self:
d = {...whatever you need...}
return d
至少有五种六种方法。首选方法取决于您的用例
备选案文1:
只需添加一个asdict()
方法
根据问题的描述,我将非常考虑<代码> Addit < /Cord>其他答案所建议的事情的方式。这是因为它并没有显示你的对象真的是一个集合:
class Wharrgarbl(object):
...
def asdict(self):
return {'a': self.a, 'b': self.b, 'c': self.c}
使用下面的其他选项可能会让其他人感到困惑,除非非常清楚哪些对象成员会被迭代,哪些不会被指定为键值对
备选案文1a:
继承您的类(或大部分等效类),并使用为您提供的
from typing import NamedTuple
class Wharrgarbl(NamedTuple):
a: str
b: str
c: str
sum: int = 6
version: str = 'old'
使用命名元组是一种非常方便的方法,可以用最少的工作量向类中添加大量功能,包括。但是,如上所示,NT将在其\u asdict
中包含所有成员
如果有您不想包含在词典中的成员,则需要修改\u asdict
结果:
from typing import NamedTuple
class Wharrgarbl(NamedTuple):
a: str
b: str
c: str
sum: int = 6
version: str = 'old'
def _asdict(self):
d = super()._asdict()
del d['sum']
del d['version']
return d
另一个限制是NT是只读的。这可能是可取的,也可能不是可取的
备选案文2:
实施
比如说:
def __iter__(self):
yield 'a', self.a
yield 'b', self.b
yield 'c', self.c
现在,您只需执行以下操作:
dict(my_object)
这是因为dict()
构造函数接受的iterable(键,值)
成对构造字典。在执行此操作之前,请自问这样一个问题:以这种方式将对象作为一系列键、值对进行迭代(同时方便创建dict
)在其他上下文中是否真的是令人惊讶的行为。例如,自问“应该列出的行为是什么?”(我的对象)
be…?”
此外,请注意,使用get itemobj[“a”]
语法直接访问值将不起作用,关键字参数解包也不起作用。对于这些,您需要实现映射协议
备选案文3:
.This允许通过键行为进行访问,在不使用\uuuuu iter\uuuuuu
的情况下强制转换到dict
,并且还提供解包行为({**my\u obj}
)和关键字解包行为(如果所有键都是字符串(dict(**my\u obj)
)
映射协议要求您(至少)同时提供两种方法:keys()
和\uuu getitem\uu
class MyKwargUnpackable:
def keys(self):
return list("abc")
def __getitem__(self, key):
return dict(zip("abc", "one two three".split()))[key]
现在,您可以执行以下操作:
>>> m=MyKwargUnpackable()
>>> m["a"]
'one'
>>> dict(m) # cast to dict directly
{'a': 'one', 'b': 'two', 'c': 'three'}
>>> dict(**m) # unpack as kwargs
{'a': 'one', 'b': 'two', 'c': 'three'}
如上所述,如果您使用的是足够新的python版本,那么您还可以将映射协议对象解包到类似这样的字典理解中(在这种情况下,您的键不需要是字符串):
请注意,当直接将对象强制转换为dict
时(无需使用kwarg解包,即dict(m)
),映射协议优先于\uuuu iter\uuu
方法。因此,当对象用作iterable时(例如,list(m)
),可能导致对象具有不同的行为,有时也很方便与转换为dict
(dict(m)
)时的对比
强调:仅仅因为您可以使用映射协议,并不意味着您应该这样做。将对象作为一组键值对或关键字参数和值传递到底有意义吗
from dataclasses import dataclass, asdict, field, InitVar
@dataclass
class Wharrgarbl(object):
a: int
b: int
c: int
sum: InitVar[int] # note: InitVar will exclude this from the dict
version: InitVar[str] = "old"
def __post_init__(self, sum, version):
self.sum = 6 # this looks like an OP mistake?
self.version = str(version)
>>> asdict(Wharrgarbl(1,2,3,4,"X"))
{'a': 1, 'b': 2, 'c': 3}
class Wharrgarbl(TypedDict):
a: str
b: str
c: str
>>> w = Wharrgarbl(a=1,b=2,b=3)
>>> w
{'a': 1, 'b': 2, 'c': 3}
>>> type(w)
<class 'dict'>
class MyDict(TypedDict):
def my_fancy_method(self):
return "world changing result"
>>> MyDict().my_fancy_method()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'my_fancy_method'
class MyClass:
def __init__(self,x,y,z):
self.x = x
self.y = y
self.z = z
def __iter__(self): #overridding this to return tuples of (key,value)
return iter([('x',self.x),('y',self.y),('z',self.z)])
dict(MyClass(5,6,7)) # because dict knows how to deal with tuples of (key,value)
class A(object):
def __init__(self, a, b, c, sum, version='old'):
self.a = a
self.b = b
self.c = c
self.sum = 6
self.version = version
def __int__(self):
return self.sum + 9000
def __iter__(self):
return self.__dict__.iteritems()
a = A(1,2,3,4,5)
print dict(a)
def to_dict(self):
class_vars = vars(MyClass) # get any "default" attrs defined at the class level
inst_vars = vars(self) # get any attrs defined on the instance (self)
all_vars = dict(class_vars)
all_vars.update(inst_vars)
# filter out private attributes
public_vars = {k: v for k, v in all_vars.items() if not k.startswith('_')}
return public_vars
def update(self, other=(), /, **kwds):
''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F.
If E present and has a .keys() method, does: for k in E: D[k] = E[k]
If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v
In either case, this is followed by: for k, v in F.items(): D[k] = v
'''
if isinstance(other, Mapping):
for key in other:
self[key] = other[key]
elif hasattr(other, "keys"):
for key in other.keys():
self[key] = other[key]
else:
for key, value in other:
self[key] = value
for key, value in kwds.items():
self[key] = value
class Wharrgarbl(object):
def __init__(self, a, b, c, sum, version='old'):
self.a = a
self.b = b
self.c = c
self.sum = 6
self.version = version
def __int__(self):
return self.sum + 9000
def __keys__(self):
return ["a", "b", "c"]
def __getitem__(self, key):
# have obj["a"] -> obj.a
return self.__getattribute__(key)
>>> w = Wharrgarbl('one', 'two', 'three', 6)
>>> dict(w)
{'a': 'one', 'c': 'three', 'b': 'two'}
def convert_to_dict(args: dict):
json = dict()
for key, value in args.items():
key_vals = str(key).split("_")
last_index = len(key_vals)
json[str(key_vals[last_index-1])] = value
return json