datetime - 注释日期时间对象的推荐方法是什么?
问题描述
假设我有一个函数,它需要两个日期时间并以秒为单位返回差:
import datetime
def diff(d1: datetime.datetime, d2: datetime.datetime) -> float:
return (d2 - d1).total_seconds()
if __name__ == '__main__':
d1 = datetime.datetime.now()
d2 = datetime.datetime.now(datetime.timezone.utc)
print(diff(d1, d2))
mypy 告诉我这很好:
$ python3.8 -m mypy test.py
Success: no issues found in 1 source file
但我得到一个类型错误:
TypeError: can't subtract offset-naive and offset-aware datetimes
错误消息中清楚地说明了原因。类型注释不够好。
我想这是一个很常见的情况。是否有推荐的方法来注释时区感知与不感知日期时间对象,从而正确使用 mypy?
解决方案
一种可能的解决方案是使用 TypeVar、NewType 和 cast:
import datetime
from typing import NewType, TypeVar, cast
NDT = NewType("NDT", datetime.datetime) # non-aware datetime
ADT = NewType("ADT", datetime.datetime) # timezone aware datetime
DatetimeLike = TypeVar("DatetimeLike", NDT, ADT)
def diff(d1: DatetimeLike, d2: DatetimeLike) -> float:
return (d2 - d1).total_seconds()
if __name__ == "__main__":
d1: NDT = cast(NDT, datetime.datetime.now())
d2: ADT = cast(ADT, datetime.datetime.now(datetime.timezone.utc))
# Fails with:
# error: Value of type variable "DatetimeLike" of "diff" cannot be "datetime"
# You have to use either NDT or ADT
print(diff(d1, d2))
我不喜欢您必须使用cast
的这种解决方案,并且错误消息不像以前那么清晰。
推荐阅读
- java - 将文本从一个活动添加到另一个活动的错误
- python - SVC 模型 - ValueError:数据不是二进制且未指定 pos_label
- c++ - 使用函数分配内存时会发生什么?
- java - Java 无法在 switch 中达到 case 283
- azure - Azure 规模集 ARM 模板重新部署重置节点计数
- angular - 英雄之旅教程——似乎 *ngFor 不起作用
- excel - VBA 宏返回连续的月末,最好不循环
- angular - 在 Angular TS 文件中找不到 Angular Input 属性
- dart - 如何修复未捕获的错误:需要一个“LIElement”类型的值,但得到一个“_JsonMap”类型的值
- r - 如何在R中格式化SPEI包的硬编码绘图功能的x轴?