【发布时间】:2019-09-20 01:00:57
【问题描述】:
我想创建一个像字符串一样“行为”的对象,但是当它被访问时,会触发一个函数并返回该结果。
__str__ 和__repr__ 的简单案例很简单;但我不知道如何让json.dumps 以同样的方式对待它;
import json, datetime
class DynamicString(str):
def __init__(self, genf):
self.generate = genf
def __repr__(self):
print("Called Repr")
return self.generate()
def __str__(self):
print("Called Str")
return self.generate()
dater=DynamicString(lambda: datetime.datetime.now().isoformat())
print(f"{dater!s}, {dater!r}, {dater!a}")
>>> Called Str
>>> Called Repr
>>> Called Repr
>>> 2019-05-01T13:52:12.588907, 2019-05-01T13:52:12.588933, 2019-05-01T13:52:12.588950
print(json.dumps(dater))
>>> "<function <lambda> at 0x10bb48730>"
似乎json.dumps 正在评估它忽略自定义 dunder 方法的对象。
我不能使用自定义JSONEncoder,因为该对象旨在通过我无权修改的模块发送。有任何想法吗?
澄清更新:
预期输出
json.dumps(dater)
>>> '"2019-05-01T16:43:21.956985"'
即"就好像它只是一个普通的字符串,但是基于当前时间"
【问题讨论】:
-
您从
str继承是否有特殊原因未在此处显示?或者你可以从其他东西继承吗? -
你不能
json.dumps(str(dater))吗?或者构建自己的序列化方法以防出现更复杂的行为? -
@Error-SyntacticalRemorse:在
dumps中更改default将不起作用,因为default仅用于JSONEncoder尚不知道如何处理的对象(请参阅@ 987654323@)。换句话说,它不会被使用,因为isinstance(dater, str)是True。它适用于您链接到的答案,因为类Doc不是从表中显示的内容派生的。 -
支持:从您的最后评论来看,听起来您的类不需要从
str派生,只是或多或少像一个。如果这是真的,那可能还有希望。但是,您还没有说出在生成的 JSON 输出上使用loads()后想要或期望得到什么。
标签: python json string serialization