您知道是否有一个内置函数可以从任意对象构建字典吗?我想这样做:
>>> class Foo:
... bar = 'hello'
... baz = 'world'
...
>>> f = Foo()
>>> props(f)
{ 'bar' : 'hello', 'baz' : 'world' }
注意:它不应该包括方法。只有字段。
您知道是否有一个内置函数可以从任意对象构建字典吗?我想这样做:
>>> class Foo:
... bar = 'hello'
... baz = 'world'
...
>>> f = Foo()
>>> props(f)
{ 'bar' : 'hello', 'baz' : 'world' }
注意:它不应该包括方法。只有字段。
当前回答
PYTHON 3:
class DateTimeDecoder(json.JSONDecoder):
def __init__(self, *args, **kargs):
JSONDecoder.__init__(self, object_hook=self.dict_to_object,
*args, **kargs)
def dict_to_object(self, d):
if '__type__' not in d:
return d
type = d.pop('__type__')
try:
dateobj = datetime(**d)
return dateobj
except:
d['__type__'] = type
return d
def json_default_format(value):
try:
if isinstance(value, datetime):
return {
'__type__': 'datetime',
'year': value.year,
'month': value.month,
'day': value.day,
'hour': value.hour,
'minute': value.minute,
'second': value.second,
'microsecond': value.microsecond,
}
if isinstance(value, decimal.Decimal):
return float(value)
if isinstance(value, Enum):
return value.name
else:
return vars(value)
except Exception as e:
raise ValueError
现在你可以在你自己的类中使用上面的代码:
class Foo():
def toJSON(self):
return json.loads(
json.dumps(self, sort_keys=True, indent=4, separators=(',', ': '), default=json_default_format), cls=DateTimeDecoder)
Foo().toJSON()
其他回答
Try:
from pprint import pformat
a_dict = eval(pformat(an_obj))
内置的dir会给你所有对象的属性,包括特殊的方法,如__str__, __dict__和一大堆你可能不想要的其他方法。但是你可以这样做:
>>> class Foo(object):
... bar = 'hello'
... baz = 'world'
...
>>> f = Foo()
>>> [name for name in dir(f) if not name.startswith('__')]
[ 'bar', 'baz' ]
>>> dict((name, getattr(f, name)) for name in dir(f) if not name.startswith('__'))
{ 'bar': 'hello', 'baz': 'world' }
所以可以扩展它,只返回数据属性,而不返回方法,通过定义你的props函数:
import inspect
def props(obj):
pr = {}
for name in dir(obj):
value = getattr(obj, name)
if not name.startswith('__') and not inspect.ismethod(value):
pr[name] = value
return pr
我认为最简单的方法是为类创建一个getitem属性。如果需要写入对象,可以创建自定义setattr。下面是一个getitem的例子:
class A(object):
def __init__(self):
self.b = 1
self.c = 2
def __getitem__(self, item):
return self.__dict__[item]
# Usage:
a = A()
a.__getitem__('b') # Outputs 1
a.__dict__ # Outputs {'c': 2, 'b': 1}
vars(a) # Outputs {'c': 2, 'b': 1}
Dict将对象属性生成到字典中,可以使用字典对象获取所需的项。
Python 3.7+将于2023年发布
您可以将数据类装饰器添加到类中,并定义一个自定义JSON序列化器,然后是JSON。转储将工作(通过向cls提供自定义编码器)。
f=Foo()
json.dumps(f, cls=CustomJSONEncoder)
{"bar": "hello", "baz": "world", "modified": "2023-02-08T11:49:15.675837"}
可以很容易地修改定制JSON序列化器,使其与任何原生JSON不可序列化的类型兼容。
from datetime import datetime
import dataclasses
import json
@dataclasses.dataclass # <<-- add this decorator
class Foo():
"""An example dataclass."""
bar: str = "hello"
baz: str = "world"
modified: datetime = Column(DateTime(timezone=True), default=datetime.utcnow)
class CustomJSONEncoder(json.JSONEncoder): # <<-- Add this custom encoder
"""Custom JSON encoder for the DB class."""
def default(self, o):
if dataclasses.is_dataclass(o): # this serializes anything dataclass can handle
return dataclasses.asdict(o)
if isinstance(o, datetime): # this adds support for datetime
return o.isoformat()
return super().default(o)
为了进一步将其扩展到任何不可序列化的类型,在自定义编码器类中添加另一个if语句,返回可序列化的内容(例如str)。
Dataclass(来自Python 3.7)是另一个可用于将类属性转换为dict的选项。Asdict可以与数据类对象一起使用 为了转换。
例子:
@dataclass
class Point:
x: int
y: int
p = Point(10, 20)
asdict(p) # it returns {'x': 10, 'y': 20}