首页 > 编程问答 >类型提示和@singledispatch:如何以可扩展的方式包含 `Union[...]`?

类型提示和@singledispatch:如何以可扩展的方式包含 `Union[...]`?

时间:2024-07-31 07:38:05浏览次数:10  
标签:python python-typing single-dispatch

我正在重构一个函数,该函数将各种日期格式(即 ISO 8601 字符串、 datetime.date datetime.datetime 等)转换为 Unix 时间戳。

我希望新函数使用 @singledispatch 而不是类型检查,但我不知道如何保留以前函数的类型提示:

旧函数:使用类型检查

import datetime
from typing import Union


MyDateTimeType = Union[int, str, datetime.datetime, datetime.date, None]


# How do I retain this functionality with @singledispatch?
#                    ⬇️⬇️⬇️⬇️⬇️⬇️⬇️
def to_unix_ts(date: MyDateTimeType = None) -> Union[int, None]:
    """Convert various date formats to Unix timestamp..."""
    if type(date) is int or date is None:
        return date

    if type(date) is str:
        # Handle string argument...

    elif type(date) is datetime.datetime:
        # Handle datetime argument...

    elif type(date) is datetime.date:
        # Handle date argument...

新函数:使用 @singledispatch

import datetime
from functools import singledispatch
from typing import Union


@singledispatch
def to_unix_ts(date) -> Union[int, None]:
    """Handle generic case (probably string type)..."""

@to_unix_ts.register
def _(date: int) -> int:
    return date


@to_unix_ts.register
def _(date: None) -> None:
    return date


@to_unix_ts.register
def _(date: datetime.datetime) -> int:
    return int(date.replace(microsecond=0).timestamp())


# etc...

我已经探索过构建支持的类型,如下所示:| ||...这样它就可以通过未来的@singledispatch 注册进行扩展,但我无法让它工作。

supported_types = [type for type in to_unix_ts.registry.keys()]
MyDateTimeType = Union(supported_types)  # Example, doesn't work

如何以可扩展的方式在

函数中添加 Union[...] 样式类型提示? @singledispatch function in an extensible way?


可以使用 typing.overload 为的 @singledispatch 函数提供干净且可扩展的类型提示。 overload 允许为同一函数定义多个类型签名,而实际实现由运行时调度处理。

以下是使用 overload 重构函数的方法:

import datetime
from functools import singledispatch
from typing import Union, overload


@overload
def to_unix_ts(date: int) -> int:
    ...


@overload
def to_unix_ts(date: None) -> None:
    ...


@overload
def to_unix_ts(date: datetime.datetime) -> int:
    ...


@overload
def to_unix_ts(date: datetime.date) -> int:
    ...


@overload
def to_unix_ts(date: str) -> int:
    ...


@to_unix_ts.register
def _(date: int) -> int:
    return date


@to_unix_ts.register
def _(date: None) -> None:
    return date


@to_unix_ts.register
def _(date: datetime.datetime) -> int:
    return int(date.replace(microsecond=0).timestamp())


@to_unix_ts.register
def _(date: datetime.date) -> int:
    # 处理日期参数...
    pass


@to_unix_ts.register
def _(date: str) -> int:
    # 处理字符串参数...
    pass

说明:

  1. @overload 装饰器: 我们为 to_unix_ts 定义了多个 @overload 装饰的函数,每个装饰器都指定了特定类型的参数和返回值。这些都不会定义实现。
  2. 单一实现: @singledispatch 和它的注册处理实际实现,就像之前一样。
  3. 类型提示改进: @overload 装饰器告诉类型检查器, to_unix_ts 可以接受不同的类型并返回相应的类型,从而提供准确的类型提示,而无需 Union

现在,当使用 to_unix_ts 时,类型检查器将使用 @overload 签名来推断正确的类型,并且 @singledispatch 机制将在运行时处理正确的实现。这提供了类型安全性和可扩展性。

标签:python,python-typing,single-dispatch
From: 61721761

相关文章

  • 激活虚拟环境会让python消失?
    VisualStudioCode终端的屏幕截图如屏幕截图所示,python在Powershell中运行得很好。然后我在E:\DrewFTCAPI\ftcapivenv激活虚拟环境,然后python就消失了。不仅没有消失,它不运行任何东西,也不产生任何输出。我至少预计会出现某种类型的"python"i......
  • Python 3.6 中的相互递归类型,使用命名元组语法
    我正在尝试实现图的节点和边。这是我的代码:fromtypingimportNamedTuple,ListclassNode(NamedTuple):name:stredges:List[Edge]classEdge(NamedTuple):src:Nodedest:Node这会引发错误,因为创建Edge时未定义Node类型。......
  • 使用 keras 模型对函数进行 Python 类型提示
    如果我创建这样的函数:defmdl(input_shape):model=Sequential()model.add(Conv2D(depth=64,kernel_size=(3,3),input_shape=input_shape,activation='relu'))model.add(Dense(32),activation='relu')model.add(Dropout(0.3))m......
  • Python:自动完成可以用于列表中的元素吗?
    Python在函数参数和函数返回类型中具有类型提示。类的元素是否有类似的东西?我希望能够在如下示例中使用自动完成功能:classMyClass:defhello(self):print("Hello")mylist=[]mylist.append(MyClass())foriinmylist:i.hello()#Noautocomplete......
  • python 中 COM 对象的正确类型提示是什么?
    我在python中使用COM对象来向3rd方软件公开可编程接口。这是通过使用Dispatchfromwin32com.client来实现的。我的项目也一直在使用python.3.7中的类型提示,但是我不确定如何为了类型提示的目的定义这些COM对象的类型。这个问题涉及我拥有的所有COM......
  • 如何遍历Python字典同时避免KeyErrors?
    解析大型JSON时,某些键可能仅在某些情况下存在,例如出现错误时。从服务器的API获取200OK的情况并不少见,但是您得到的响应包含应检查的错误。处理此问题的最佳方法是什么?我知道使用类似||之类的东西。|是处理KeyError的一种方法。get()但是如果......
  • Python 中的递归数据类型
    Python中最接近Haskell中的递归数据类型的是什么?(即在定义自身时使用类型自己的定义。)编辑:为了给出递归类型的更具体定义,下面是Haskell中的二叉树:dataTreea=Leafa|Branch(Treea)(Treea)我的阅读方式如下:二叉树可以是叶子,也可以包含两......
  • 如何在Python中平滑相邻的多边形?
    我正在寻找一种平滑多边形的方法,以便相邻/接触的多边形保持接触。单个多边形可以轻松平滑,例如使用PAEK或Bezier插值(https://pro.arcgis.com/en/pro-app/latest/tool-reference/cartography/smooth-polygon.htm),这自然会改变它们的边界边缘。但是如何平滑所有多边形......
  • Python多处理池不启动多个进程
    我正在尝试使用多处理池来创建多个进程。我有一个工作函数dummy_proc定义如下:importrefrommultiprocessingimportPooldefregex_check(input_string):#Patterntomatchboth"pm_lat"and"pm_lon_coslat"followedbytwofloatspattern=r"(c......
  • 迟滞建模作为 Python GEKKO 中 MPC 的控制约束
    我试图使用PythonGEKKO在用于控制信号调度的MPC优化问题中引入滞后约束。这已成为一项艰巨的任务,因为我无法将以下问题转换为GEKKO理解的方程。问题:如果开启时间<最短开启时间,则给定资产的控制调度不应将其关闭。如果关闭时间<最小关闭时间......