タイピングtyping.Any
とは対照的に使用することに違いはありますか? object
例えば:
def get_item(L: list, i: int) -> typing.Any:
return L[i]
に比べ:
def get_item(L: list, i: int) -> object:
return L[i]
タイピングtyping.Any
とは対照的に使用することに違いはありますか? object
例えば:
def get_item(L: list, i: int) -> typing.Any:
return L[i]
に比べ:
def get_item(L: list, i: int) -> object:
return L[i]
はい、違いがあります。Python 3 では、すべてのオブジェクトは、それ自体object
を含めて のインスタンスですが、戻り値がタイプチェッカーによって無視されるべきであるというドキュメントだけがあります。object
Any
Any
タイプ docstring は、 object が のサブクラスでAny
あり、その逆であることを示しています。
>>> import typing
>>> print(typing.Any.__doc__)
Special type indicating an unconstrained type.
- Any object is an instance of Any.
- Any class is a subclass of Any.
- As a special case, Any and object are subclasses of each other.
ただし、適切なタイプチェッカー (チェックを超えてisinstance()
、オブジェクトが関数で実際にどのように使用されているかを検査するもの)は、常に受け入れられるobject
場所にすぐに異議を唱えることができます。Any
Any
type の値をより正確な型に代入する場合、型チェックは実行されないことに注意してください。
と
の動作
Any
と の動作を比較してobject
ください。と同様にAny
、すべてのタイプは のサブタイプですobject
。ただし、 とは異なりAny
、その逆は当てはまりません。オブジェクトは、他のすべての型のサブタイプではありません。つまり、値の型が の場合
object
、型チェッカーはその値に対するほとんどすべての操作を拒否し、それをより特殊な型の変数に割り当てる (または戻り値として使用する) と、型エラーになります。
および mypy ドキュメント セクションAny vs. objectから:
型
object
は、任意の型のインスタンスを値として持つことができる別の型です。とは異なりAny
、object
は通常の静的型 (Object
Java と同様) であり、すべての型に対して有効な操作のみがオブジェクト値に対して受け入れられます。
object
より具体的な型にキャストできますが、Any
実際には何でもあり、型チェッカーがオブジェクトの使用から解放されることを意味します (後でそのようなオブジェクトを型チェックされた名前に割り当てたとしても)。
を受け入れることで、型付けされていないコーナーに関数を既に描画しました。list
これは、 と同じことになりList[Any]
ます。タイプチェッカーはそこで解放され、戻り値はもはや重要ではありませんが、関数はAny
オブジェクトを含むリストを受け入れるため、適切な戻り値はAny
ここにあります。
List[T]
タイプチェックされたコードに適切に参加するには、タイプチェッカーが戻り値を処理できるように、入力を (一般的に型指定されたコンテナー)としてマークする必要があります。あなたの場合はT
、リストから値を取得しているためです。T
から作成TypeVar
:
from typing import TypeVar, List
T = TypeVar('T')
def get_item(L: List[T], i: int) -> T:
return L[i]
Any
とobject
は表面的には似ていますが、実際にはまったく反対の意味を持っています。
object
Python のメタクラス階層のルートです。すべての単一クラスは から継承しobject
ます。これはobject
、ある意味で、値を与えることができる最も制限的な型であることを意味します。type の値を持っている場合、object
呼び出すことが許可されているメソッドは、すべてのオブジェクトの一部であるメソッドだけです。例えば:
foo = 3 # type: object
# Error, not all objects have a method 'hello'
bar = foo.hello()
# OK, all objects have a __str__ method
print(str(foo))
対照的に、Any
は、動的に型付けされたコードと静的に型付けされたコードを混在させるためのエスケープ ハッチです。Any
は最も制限の少ないタイプです。 type の値に対して、考えられるすべてのメソッドまたは操作が許可されますAny
。例えば:
from typing import Any
foo = 3 # type: Any
# OK, foo could be any type, and that type might have a 'hello' method
# Since we have no idea what hello() is, `bar` will also have a type of Any
bar = foo.hello()
# Ok, for similar reasons
print(str(foo))
通常は、次の場合にのみ試して使用する必要Any
があります...
Dict[str, Any]
。これは、何もないよりは少しましです。対照的にobject
、値が存在する可能性のあるオブジェクトで文字通り機能しなければならないことをタイプセーフな方法で示したい場合に使用します。
Any
代替手段がない場合を除いて、使用を避けることをお勧めします。Any
は譲歩です。タイプセーフな世界に住みたいと思うダイナミズムを可能にするメカニズムです。
詳細については、次を参照してください。
特定の例では、オブジェクトまたは Any ではなく、TypeVarsを使用します。あなたがしたいことは、リストに含まれているものの型を返したいことを示すことです。リストに常に同じタイプが含まれる場合 (通常はそうです)、次のようにします。
from typing import List, TypeVar
T = TypeVar('T')
def get_item(L: List[T], i: int) -> T:
return L[i]
このようにして、get_item
関数は可能な限り正確な型を返します。