次のクラスが与えられます:
from typing import AnyStr
class A(object):
def __init__(self, param):
# type: (AnyStr) -> None
self.a = param # type: AnyStr
次の出力が得られます。
$ mypy . -v
LOG: Mypy version 0.521
LOG: Build finished in 1.199 seconds with 10 modules, 2076 types, and 2 errors
test.py:8: error: Incompatible types in assignment (expression has type "str", variable has type "AnyStr")
test.py:8: error: Incompatible types in assignment (expression has type "bytes", variable has type "AnyStr"
この割り当て操作で互換性のないタイプが生成されるのはなぜですか?
私はmypyの専門家ではありませんが、少しの探偵の仕事で、これを理解したと思います。
これはAnyStr
、関数に渡された場合は問題なく機能するようですが、変数がAnyStr
。として入力された場合は失敗します。たとえば、これは正常に機能しているようです。
from typing import AnyStr
def f(a):
# type: (AnyStr) -> AnyStr
return a
if __name__ == "__main__":
print(f('cat'))
print(f(b'dog'))
しかし、これは失敗します:
from typing import AnyStr
c = 3 # type: AnyStr
エラーあり:
mypy_anystr.py:3: error: Invalid type "typing.AnyStr"
ドキュメントAnyStr
からの、の考え方は、またはのいずれかを意図しているためですが、特定の関数呼び出しの範囲内で一貫している必要があるため、これは理にかなっています。彼らが使用法について与える例は次のとおりです。 str
bytes
AnyStr
def concat(a, b):
#type: (AnyStr, AnyStr) -> AnyStr
return a + b
concat('one', 'two') # OK
concat(b'three', b'four') # OK
concat('five', b'six') # Error
もちろん、AnyStr
がグローバルでない限り(そして上記の例がそうではないことを示している)、元のAnyStr
変数のスコープ外の変数(たとえば、グローバル、またはクラスの属性)を割り当てることは意味がありません。なぜ失敗するのか。エラーメッセージはこれについてはるかに明確である可能性があると思います。
実際に達成したいことに応じて、ここにはいくつかの解決策があります。str
との間で本当に不可知論者である場合はbytes
、次を使用できますUnion[Text, bytes]
。
import Union、Text、AnyStrの入力から
class A:
def __init__(self, a):
#type: (AnyStr) -> None
self.param = a # type: Union[Text, bytes]
この場合AnyStr
、入力で使用したことに注意してください。ただし、この場合Union[Text, bytes]
、パラメーターが1つしかないため、と同等です。あなたが実際にあれば別の方法として、やるパラメータがあるかどうかを気にstr
かbytes
、あなただけ取ることができAnyStr
、あなたが積極的にしたいバージョンに変換します。
from typing import Union, Text, AnyStr
from six import binary_type
class A:
def __init__(self, a):
#type: (AnyStr) -> None
if isinstance(a, binary_type):
b = a.decode() # type: Text
else:
b = a
self.param = b # type: Text
a
奇妙なロケールなどでエンコードされている場合、これはファンキーになる可能性があることに注意してください。したがって、これは単純化された例であり、bytes
オブジェクトをアクティブにデコードしようとする場合はYMMVであることに注意してください。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加