mypy 抱怨:带有 Type[TypeVar['T', str, date]] 和 T 输出的函数类型注释:不兼容 return 值类型(得到 "str",预期 "date")
mypy complains: function type annotation with Type[TypeVar['T', str, date]] and T output: Incompatible return value type (got "str", expected "date")
目的是重载函数并允许多种类型的输入,以及用户定义的连贯输出。
因此,我设置了 Type[TypeVar]
of str
or datetime.date
(第二个函数参数,默认值=str
),函数将输出相关的 TypeVar
.
以下是基本功能(待此版本修复后我会进一步扩展):
from typing import TypeVar, Type
from datetime import date, datetime
DateOutType = TypeVar('DateOutType', str, date)
def date2str(t: date, out_format: Type[DateOutType]=Type[str]) -> DateOutType:
''' Converts datetime.date to string (YYYY-MM-DD) or datetime.date output.
'''
if out_format is str:
return t.strftime('%Y-%m-%d')
elif isinstance(t, datetime):
return t.date()
else:
return t
# Usage example:
dt = datetime.now()
res = date2str(dt, out_format=date)
assert type(res) == date
res = date2str(dt.date(), out_format=str)
assert type(res) == str
mypy 在 return 语句中给出错误(TypeVar 似乎没有像我预期的那样工作):
first return statement: error: Incompatible return value type (got "str", expected "date")
second return statement: error: Incompatible return value type (got "date", expected "str")
third return statement: error: Incompatible return value type (got "date", expected "str")
有什么想法吗?
有没有更好的方法来使用正确的类型注释来编写此代码?
这里的问题是 mypy 不理解 some_type is str
或 type(some_value) is str
形式的表达式。您需要改为执行 issubclass(some_type, str)
或 isinstance(some_value, str)
。
也就是说,在这种情况下,只创建两个不同的函数会更简洁:
def date_to_str(t: date) -> str:
return t.strftime('%Y-%m-%d')
def normalize_date(t: date) -> date:
if isinstance(t, datetime):
return t.date()
return t
这最终会减少用户键入的字符,因为他们不需要在所有地方都包含 out_format=date
或 out_format=str
。它的误导性也更小:您的原始函数实际上并不总是 return 一个 str,所以称它为 date2str
有点令人困惑。
完全删除 normalize_date
也可能是个好主意:日期时间是日期的子类,这意味着在任何需要日期的地方使用日期时间都是有效的。这意味着确实不需要将日期时间显式转换为日期
例如,以下两个打印将做完全相同的事情(根据 mypy 将键入检查):
from datetime import datetime
dt = datetime.now()
print(date_to_str(dt))
print(date_to_str(normalize_date(dt)))
目的是重载函数并允许多种类型的输入,以及用户定义的连贯输出。
因此,我设置了 Type[TypeVar]
of str
or datetime.date
(第二个函数参数,默认值=str
),函数将输出相关的 TypeVar
.
以下是基本功能(待此版本修复后我会进一步扩展):
from typing import TypeVar, Type
from datetime import date, datetime
DateOutType = TypeVar('DateOutType', str, date)
def date2str(t: date, out_format: Type[DateOutType]=Type[str]) -> DateOutType:
''' Converts datetime.date to string (YYYY-MM-DD) or datetime.date output.
'''
if out_format is str:
return t.strftime('%Y-%m-%d')
elif isinstance(t, datetime):
return t.date()
else:
return t
# Usage example:
dt = datetime.now()
res = date2str(dt, out_format=date)
assert type(res) == date
res = date2str(dt.date(), out_format=str)
assert type(res) == str
mypy 在 return 语句中给出错误(TypeVar 似乎没有像我预期的那样工作):
first return statement: error: Incompatible return value type (got "str", expected "date")
second return statement: error: Incompatible return value type (got "date", expected "str")
third return statement: error: Incompatible return value type (got "date", expected "str")
有什么想法吗? 有没有更好的方法来使用正确的类型注释来编写此代码?
这里的问题是 mypy 不理解 some_type is str
或 type(some_value) is str
形式的表达式。您需要改为执行 issubclass(some_type, str)
或 isinstance(some_value, str)
。
也就是说,在这种情况下,只创建两个不同的函数会更简洁:
def date_to_str(t: date) -> str:
return t.strftime('%Y-%m-%d')
def normalize_date(t: date) -> date:
if isinstance(t, datetime):
return t.date()
return t
这最终会减少用户键入的字符,因为他们不需要在所有地方都包含 out_format=date
或 out_format=str
。它的误导性也更小:您的原始函数实际上并不总是 return 一个 str,所以称它为 date2str
有点令人困惑。
完全删除 normalize_date
也可能是个好主意:日期时间是日期的子类,这意味着在任何需要日期的地方使用日期时间都是有效的。这意味着确实不需要将日期时间显式转换为日期
例如,以下两个打印将做完全相同的事情(根据 mypy 将键入检查):
from datetime import datetime
dt = datetime.now()
print(date_to_str(dt))
print(date_to_str(normalize_date(dt)))