ten*_*nni 6 python type-hinting single-dispatch
我正在重构一个将各种日期格式(即 ISO 8601 字符串、 、 等)转换datetime.date为datetime.datetimeUnix 时间戳的函数。
我希望使用新函数@singledispatch而不是类型检查,但我不知道如何保留前一个函数的类型提示:
import datetime\nfrom typing import Union\n\n\nMyDateTimeType = Union[int, str, datetime.datetime, datetime.date, None]\n\n\n# How do I retain this functionality with @singledispatch?\n# \xe2\xac\x87\xef\xb8\x8f\xe2\xac\x87\xef\xb8\x8f\xe2\xac\x87\xef\xb8\x8f\xe2\xac\x87\xef\xb8\x8f\xe2\xac\x87\xef\xb8\x8f\xe2\xac\x87\xef\xb8\x8f\xe2\xac\x87\xef\xb8\x8f\ndef to_unix_ts(date: MyDateTimeType = None) -> Union[int, None]:\n """Convert various date formats to Unix timestamp..."""\n if type(date) is int or date is None:\n return date\n\n if type(date) is str:\n # Handle string argument...\n\n elif type(date) is datetime.datetime:\n # Handle datetime argument...\n\n elif type(date) is datetime.date:\n # Handle date argument...\nRun Code Online (Sandbox Code Playgroud)\n\n@singledispatchimport datetime\nfrom functools import singledispatch\nfrom typing import Union\n\n\n@singledispatch\ndef to_unix_ts(date) -> Union[int, None]:\n """Handle generic case (probably string type)..."""\n\n@to_unix_ts.register\ndef _(date: int) -> int:\n return date\n\n\n@to_unix_ts.register\ndef _(date: None) -> None:\n return date\n\n\n@to_unix_ts.register\ndef _(date: datetime.datetime) -> int:\n return int(date.replace(microsecond=0).timestamp())\n\n\n# etc...\nRun Code Online (Sandbox Code Playgroud)\n\n我已经探索过构建支持的类型,如下所示:
\n\nsupported_types = [type for type in to_unix_ts.registry.keys()]\nMyDateTimeType = Union(supported_types) # Example, doesn\'t work\nRun Code Online (Sandbox Code Playgroud)\n\n...这样它就可以通过未来的 @singledispatch 注册进行扩展,但我无法让它工作。
\n\n如何以可扩展的方式Union[...]在函数中添加样式类型提示?@singledispatch
我想这就是你要找的。请注意,singledispatch需要register(type(None))而不是register(None). 它不支持register(Union[a, b]),但您可以将多个register装饰器应用于一个函数......
import datetime
from functools import singledispatch
from typing import Union
MyDateTimeType = Union[
int,
None,
datetime.datetime,
datetime.date
]
@singledispatch
def to_unix_ts(date: MyDateTimeType) -> Union[int, None]:
raise NotImplementedError
@to_unix_ts.register(int)
@to_unix_ts.register(type(None))
def _(date: Union[int, None]) -> Union[int, None]:
return date
@to_unix_ts.register(str)
def _(date: str):
# Handle string argument...
@to_unix_ts.register(datetime.datetime)
def _(date: datetime.datetime):
# Handle datetime argument...
@to_unix_ts.register(datetime.date)
def _(date: datetime.date):
# Handle date argument...
Run Code Online (Sandbox Code Playgroud)