- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在使用 attrs
/cattrs
将自定义数据类转换为 JSON 格式时遇到问题。我的类(class)具有以下形式:
import attr
from datetime import datetime
from typing import Tuple, Set, Dict, FrozenSet
@attr.s(auto_attribs=True)
class B:
w: Set[datetime] = attr.ib()
x: Set[str] = attr.ib()
y: Set['A'] = attr.ib()
z: Set[Tuple[datetime, str]] = attr.ib(factory=set)
@attr.s(auto_attribs=True, cmp=False)
class A:
a: str = attr.ib()
b: FrozenSet[Team] = attr.ib()
c: FrozenSet[Tuple[datetime, str]] = attr.ib(factory=frozenset)
d: Dict[Tuple[str, str], float] = attr.ib(factory=dict)
我面临的问题是,当我尝试通过 cattrs.unstruct
转换为 dict
时,反之亦然通过 cattrs.struct
, cattrs
显示一个错误,告诉我应该使用钩子(Hook):
import cattr
# Create instance of b
b_instance = B(...)
...
data = cattr.unstructure(b_instance)
print()
print(data)
print()
restored = cattr.structure(data, B)
assert b_instance == restored
ValueError: Unsupported type: <class 'datetime.datetime'>. Register a structure hook for it.
我注册了一个钩子(Hook),以将datetime
转换为给定格式的str
:
import cattr
from datetime import datetime
time_format = '%Y-%m-%d %H:%M:%S'
cattr.register_unstructure_hook(datetime, lambda dt: dt.strftime(time_format))
cattr.register_structure_hook(datetime, lambda s, _: datetime.strptime(s, time_format))
但是我收到以下错误:
TypeError: strptime() argument 1 must be str, not datetime.datetime
我需要能够使用 %Y-%m-%d %H:%M:%S
格式的日期时间在对象实例和 JSON 之间进行转换。我怎样才能实现这一目标?
最佳答案
问题出在 Set 类型上。如果它存在于类型中,则 cattr.unstruct
无法序列化它。将其替换为元组,事情就会解决:
from typing import Tuple, Set
from datetime import datetime
import cattr
import attr
import pytest
TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
COMPLEX_TYPE = Tuple[Tuple[str, datetime]]
COMPLEX_TYPE_BAD = Set[Tuple[str, datetime]]
cattr.register_unstructure_hook(
datetime, lambda dt: datetime.strftime(dt, format=TIME_FORMAT)
)
cattr.register_structure_hook(
datetime, lambda dt_str, _: datetime.strptime(dt_str, TIME_FORMAT)
)
def test_cattrs_io_for_a():
@attr.s(auto_attribs=True)
class A:
ds: datetime = attr.ib(factory=datetime.utcnow)
a = A()
a_ser = cattr.unstructure(a)
a_des = cattr.structure(a_ser, A)
assert isinstance(a_des, A)
def test_cattrs_io_for_b():
@attr.s(auto_attribs=True)
class B:
ds: COMPLEX_TYPE = attr.ib(factory=set)
b = B((("a", datetime.utcnow()), ("b", datetime.utcnow())))
b_ser = cattr.unstructure(b)
b_des = cattr.structure(b_ser, B)
assert isinstance(b_des, B)
def test_cattrs_io_for_b_bad():
@attr.s(auto_attribs=True)
class B:
ds: COMPLEX_TYPE_BAD = attr.ib(factory=set)
b = B({("a", datetime.utcnow()), ("b", datetime.utcnow())})
b_ser = cattr.unstructure(b)
with pytest.raises(TypeError):
b_des = cattr.structure(b_ser, B)
assert isinstance(b_des, B)
这看起来像是cattrs https://github.com/Tinche/cattrs/issues/48 中的一个问题
将在下一版本的 cattrs 中修复。或者您可以从 master
分支构建它
关于python - 使用 cattrs 解构复杂的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55127722/
我试图找到类似于 java Jackson ObjectMapper 的解决方案可以将 python 对象序列化/反序列化为 json。并发现 cattrs最接近我需要的。但它不能像在 json 中使
我在使用 attrs/cattrs 将自定义数据类转换为 JSON 格式时遇到问题。我的类(class)具有以下形式: import attr from datetime import datetim
python 是支持面向对象的,很多情况下使用面向对象编程会使得代码更加容易扩展,并且可维护性更高,但是如果你写的多了或者某一对象非常复杂了,其中的一些写法会相当相当繁琐,而且我们会经常碰到对象和
我是一名优秀的程序员,十分优秀!