在某些情况下,Python 2 会将 str
隐式转换为 unicode
。此转换有时会抛出 UnicodeError
,具体取决于您尝试对结果值执行的操作。我不知道确切的语义,但这是我想避免的事情。
是否可以使用 unicode
之外的其他类型或类似于 --strict-optional
( http://mypy-lang.blogspot.co.uk/2016/07/mypy-043-released.html ) 的命令行参数来使程序使用此隐式转换为类型检查失败?
def returns_string_not_unicode():
# type: () -> str
return u"a"
def returns_unicode_not_string():
# type: () -> unicode
return "a"
在这个例子中,只有函数returns_string_not_unicode
类型检查失败。
$ mypy --py2 unicode.py
unicode.py: note: In function "returns_string_not_unicode":
unicode.py:3: error: Incompatible return value type (got "unicode", expected "str")
我希望他们都无法通过类型检查。
编辑:
type: () -> byte
似乎与 str
def returns_string_not_unicode():
# type: () -> bytes
return u"a"
最佳答案
不幸的是,这是一个持续存在且目前尚未解决的问题 -- 请参阅 https://github.com/python/mypy/issues/1141和 https://github.com/python/typing/issues/208 .
部分修复是使用 typing.Text
,(不幸的是)目前没有记录(不过我会努力修复它)。它的别名是 Python 3 中的 str
和 Python 2 中的 unicode
。它不会解决您的实际问题或导致第二个函数无法进行类型检查,但它 确实可以更轻松地编写与 Python 2 和 Python 3 兼容的类型。
与此同时,您可以使用最近实现的 NewType
feature 来破解部分变通办法。 -- 它允许您以最小的运行时成本定义一个伪子类,您可以使用它来近似您正在寻找的功能:
from typing import NewType, Text
# Tell mypy to treat 'Unicode' as a subtype of `Text`, which is
# aliased to 'unicode' in Python 2 and 'str' (aka unicode) in Python 3
Unicode = NewType('Unicode', Text)
def unicode_not_str(a: Unicode) -> Unicode:
return a
# my_unicode is still the original string at runtime, but Mypy
# treats it as having a distinct type from `str` and `unicode`.
my_unicode = Unicode(u"some string")
unicode_not_str(my_unicode) # typechecks
unicode_not_str("foo") # fails
unicode_not_str(u"foo") # fails, unfortunately
unicode_not_str(Unicode("bar")) # works, unfortunately
它并不完美,但如果您坚持何时将字符串提升为您的自定义 Unicode
类型,您可以获得接近您正在寻找的类型安全性的东西在 bytes/str/unicode 问题得到解决之前,以最小的运行时间成本。
请注意,您需要从 Github 的 master 分支安装 mypy 才能使用 NewType
。
请注意,NewType 是从 mypy version 0.4.4 开始添加的.
关于python - Mypy Python 2 坚持使用 unicode 值而不是字符串值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38753817/