gpt4 book ai didi

python - 向 JSON 对象 Hook 添加类型提示的正确方法

转载 作者:行者123 更新时间:2023-12-04 03:59:21 25 4
gpt4 key购买 nike

json module docs 中的示例为例:

>>> def as_complex(dct):
... if '__complex__' in dct:
... return complex(dct['real'], dct['imag'])
... return dct

在这里添加类型提示的正确方法是什么?我使用 TypedDict 和重载的天真方法失败了:

from typing import Any, Dict, TypedDict, TypeVar, Union, overload


_T = TypeVar('_T', bound=Dict[str, Any])


class JSONDict(TypedDict):
__complex__: Any
real: float
imag: float


@overload
def as_complex(dct: JSONDict) -> complex: ...
@overload
def as_complex(dct: _T) -> _T: ...


def as_complex(dct: _T) -> Union[complex, _T]:
if '__complex__' in dct:
return complex(dct['real'], dct['imag'])
return dct

作为 mypy 对象:

main.py:14: error: Overloaded function signatures 1 and 2 overlap with incompatible return types
main.py:19: error: Overloaded function implementation cannot satisfy signature 1 due to inconsistencies in how they use type variables

Playground gist , 如果您想在浏览器中试用示例。

最佳答案

显然 mypyJSONDict_T 视为重叠类型,很可能是由于 AnyTypeVar 定义。这让我想起了以下情况(只是示例):

class A: ...
class B: ...
class C: ...
class D: ...

@overload
def f(x: Union[A, B]) -> int: ... # E: Overloaded function signatures 1 and 2 overlap with incompatible return types
@overload
def f(x: Union[B, C]) -> str: ...
def f(x): ...

我们可以让它们重叠或尝试将它们分开。目前,我可以提出两个相当丑陋的解决方案。

from typing import Any, Dict, TypedDict, TypeVar, Union, overload, cast


_T = TypeVar('_T', bound=Dict[str, Any])


class JSONDict(TypedDict):
__complex__: Any
real: float
imag: float


@overload
def as_complex(dct: JSONDict) -> complex: ...
@overload
def as_complex(dct: _T) -> Union[_T, complex]: ...


def as_complex(dct: Union[_T, JSONDict]) -> Union[complex, _T]:
if '__complex__' in dct:
return complex(dct['real'], dct['imag'])
return cast(_T, dct)

或者尝试分开

from typing import Any, Dict, TypedDict, TypeVar, Union, overload, cast

# narrowing the list of types excluding float
_T = TypeVar('_T', bound=Dict[str, Union[int, str, list, tuple, dict, set]])


class JSONDict(TypedDict):
__complex__: Any
real: float
imag: float


@overload
def as_complex(dct: JSONDict) -> complex: ...
@overload
def as_complex(dct: _T) -> _T: ...


def as_complex(dct: Union[_T, JSONDict]) -> Union[complex, _T]:
if '__complex__' in dct:
dct = cast(JSONDict, dct)
return complex(dct['real'], dct['imag'])
return cast(_T, dct)

希望有人能提出更优雅的解决方案

关于python - 向 JSON 对象 Hook 添加类型提示的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63331368/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com