【问题标题】:How do you use Python type hints when you have messy input types?当输入类型混乱时,如何使用 Python 类型提示?
【发布时间】:2022-01-06 16:11:11
【问题描述】:

我有一个需要类似日期的对象列表的函数,我正在寻找一种添加良好类型提示的方法。

def get_prices(dates):
   ...

我现在用的是

def get_prices(dates: list[str]) -> list[float]:

但我对此并不是 100% 满意。

我可以创建一个类DateLike,然后这样做:

def get_prices(dates: list[DateLike]) -> list[float]:

但不确定这是否合适,因为根本不涉及 DateLike 类(类型提示除外)。

那时我可以做到:

def get_prices(dates: IterableOfObjectsThatCanBeCastToDatesByPandas) -> list[float]:

但随后类型提示就失去了所有意义。

【问题讨论】:

  • 当你说类似日期的对象时,你能给我们举个对象类型的例子吗?你的意思是像datetimetimedelta这样的类型吗?
  • 在这种情况下,我的代码支持日期字符串:'2020-10-05' 或日期时间对象:datetime(2020, 10, 5)
  • 但我的问题更笼统:当内置类型不够用时,我有什么选择。我想在 Python 3.10 中我可以做到 get_prices(dates:list[str|datetime])->list[float],但这仍然感觉不完整。我想我将输入验证与类型提示混为一谈。
  • 这能回答你的问题吗? Why can't List contain multiple types?
  • @MycchakaKleinbort 我建议不要同时接受。接受datetime 对象,并让调用者负责从字符串创建它们。

标签: python type-hinting


【解决方案1】:

解析类似日期的字符串不是您的函数的工作。它应该接受date对象,并让调用者首先负责解析字符串。

from datetime import datetime

def get_prices(dates: list[datetime]) -> list[float]:
    ...

prices = get_prices([datetime.strptime(x, "%Y-%m-%d") for x in datelikestrings])

调用者还负责处理无法解析的字符串(即,当strptime 引发异常而不是返回datetime 的实例时。)

【讨论】:

    【解决方案2】:

    打字模块为此有一个“联合”类:

    from typing import Union
    
    def foo(bar: Union[str,int]):
        print(bar)
    

    从 3.10 开始,您将能够编写:

    def foo(bar: str|int):
        print(bar)
    

    【讨论】:

    • 这样做的问题是它不会拒绝不能被解析为日期的字符串。
    • 类型提示不会拒绝任何东西,它是提示而不是规则。你是对的,你把类型提示和输入验证混为一谈了!
    • 没错。我想指出,如果输入是一个字符串,那么它必须是一个日期,为此我可以将str 子类化并在类型提示中使用它。但在这一点上,我不妨把它放在文档字符串中。我的意思是,这在哪里结束?如果我想暗示应该对列表进行排序怎么办?等等……
    • 类型提示不是万能的。并非所有都可以编码为类型(至少在 PEP-484 和类型检查器如mypy 实现的相对弱的类型理论中不能)。提示你可以做的事情,剩下的留给运行时测试。
    • “拒绝”是指像mypy 这样的工具。除非您实际使用的类型检查器会执行 某事,否则类型提示 并不比文档字符串好。
    猜你喜欢
    • 1970-01-01
    • 2020-10-14
    • 2018-02-23
    • 2018-07-17
    • 2023-03-29
    • 2022-10-24
    • 2016-03-19
    • 2021-12-23
    • 1970-01-01
    相关资源
    最近更新 更多