从另一种类型生成一种类型并将字段更改为可选

L42*_*L42 4 python type-hinting

我有这种类型:

class SomeResource:
    id: int
    name: str
Run Code Online (Sandbox Code Playgroud)

我需要这种类型:

class SomeResourceQuery:
    id: Optional[int]
    name: Optional[str]
Run Code Online (Sandbox Code Playgroud)

但我想避免用手写。SomeResourceQuery是否可以从类型生成该类型SomeResource?只需将所有字段类型转换为可选即可。(更新:已经可选的字段可以保持可选 - 没有嵌套的可选。)

我计划在存储库中使用它SomeResourceQuery,如下所示:

class SomeResourceRepository:
    def get_one_or_none(self, query: SomeResourceQuery) -> Optional[SomeResource]:
        ...
Run Code Online (Sandbox Code Playgroud)

更新:只是为了展示我目前的想法:

class SomeResource:
    id: int
    name: str


# I don't want to write this by hand:
# class SomeResourceQuery:
#     id: Optional[int]
#     name: Optional[str]

# So what can I do here to make all fields that are not already optional, optional?
SomeResourceQuery = type("SomeResourceQuery", SomeResource) # What to do here?
Run Code Online (Sandbox Code Playgroud)

Dan*_*ker 6

您可以使用type构造函数通过适当的注释构造新类型。

def construct_query_class(cls: type) -> type:
    annotations = {key: typing.Optional[value]
                    for key, value in cls.__annotations__.items()}

    return dataclasses.dataclass(type(cls.__name__ + 'Query', (),
                                      {'__annotations__': annotations}))

class SomeResource:
    id: int
    name: str

SomeResourceQuery = construct_query_class(SomeResource) # type: typing.Any
Run Code Online (Sandbox Code Playgroud)