如何解决为类创建装饰器以应用数据类和JsonSchemaMixin ...不起作用
我确实查看了所有现有的SO问题,并尽我所能地搜索了谷歌,尝试了几种不同的选择,但似乎无法获得我想要的工作。
背景
一个简单的问题-我的代码中有一堆数据类。
我希望将它们全部更改为从dataclasses-jsonschema
JsonSchemaMixin
继承,以便可以以编程方式为所有对象生成模式。
当然,简单的方法是我可以更改代码中的所有实例以从JsonSchemaMixin
混合继承。
但是我当时想我也可以编写自己的装饰器,以a)一次应用@ dataclass,b)mixin dataclasses-schema
。 ...我的想法是减少出错的机会,我可以尝试编写一个类装饰器(我曾经创建并使用过自己的函数装饰器)
# OLD
@dataclass
class X:
....
# Add the mixin `by hand` everywhere
@dataclass
class X(JsonSchemaMixin):
x: int
y: float
# What I want is to make my own decorator to do both:
@dataclass_mixedin
class X:
x: int
y: float
问题
一个非常简单的问题-我无法解决这个问题:(
我尝试过的
尝试编号1:
from dataclasses import dataclass
from dataclasses_jsonschema import JsonSchemaMixin
def dc_schema(cls):
@dataclass
class _decorated(JsonSchemaMixin,cls):
pass
return _decorated
@dc_schema
class Data:
x: int
y: float
a = Data(x=5,y=1.1)
以上操作失败,并带有意外的关键字args x和y。
尝试2:
def dc_schema2(cls):
# Try applying dataclass() directly:
class _decorated(JsonSchemaMixin,cls):
pass
_decorated = dataclass(_decorated)
return _decorated
@dc_schema2
class Data2:
x: int
y: float
d = Data2(x=1,y=1.1)
再次-失败,出现意外参数。
所以我猜想我缺少dataclass
遍历类结构以查找带有注释(https://docs.python.org/3/library/dataclasses.html)的类变量。
但是我不知道该怎么做
解决方法
可能的解决方案是使用元类。 参见以下示例:
from dataclasses import dataclass,is_dataclass
from dataclasses_jsonschema import JsonSchemaMixin
class EntityMeta(type):
def __new__(cls,name,bases,class_dict):
new_class = super().__new__(cls,class_dict)
return dataclass()(new_class)
class BaseEntity(JsonSchemaMixin,metaclass=EntityMeta):
pass
class SomeClass(BaseEntity):
id: str
name: str
assert is_dataclass(SomeClass)
assert issubclass(SomeClass,JsonSchemaMixin)
x = SomeClass(1,"Hello World")
assert x.id == 1
assert x.name == "Hello World"
class SomeOtherClass(BaseEntity):
foo: str
name: str
x = SomeOtherClass("foo","ufo")
assert x.foo == "foo"
assert x.name == "ufo"
print(SomeOtherClass.json_schema())
我不建议您这样做,因为您 无论如何都需要从基类继承,并且代码详细程度上的差异很小。您会失去类型等实用功能 在提供此类帮助的IDE中,在MyPy(除非编写专用插件)或Pylance的帮助下进行提示时会提示提示。
我建议考虑使用pydantic
:它可能具有您想要的功能。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。