入力時にobject
と対照的にtyping.Any
を使用するときに違いはありますか?たとえば:に比べタイピングです.Any vsオブジェクト?
def get_item(L: list, i: int) -> typing.Any:
return L[i]
:
def get_item(L: list, i: int) -> object:
return L[i]
入力時にobject
と対照的にtyping.Any
を使用するときに違いはありますか?たとえば:に比べタイピングです.Any vsオブジェクト?
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
型ドキュメンテーション文字列オブジェクトが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
の値を割り当てるときに何型チェックが行われないことに注意してください。
と
コントラスト
object
の動作とAny
の振る舞い。Any
と同様に、すべてのタイプはobject
のサブタイプです。しかし、Any
とは異なり、逆は真ではありません。オブジェクトは他のすべての型のサブタイプではありません。つまり、値の型が
object
である場合、型チェッカーはほとんどすべての操作を拒否し、それをより特殊な型の変数に(または戻り値として)割り当てることは型エラーです。
とmypyドキュメントセクションAny vs. objectから:
タイプ
object
値として任意の型のインスタンスを持つことができる別のタイプです。Any
とは異なり、object
は通常の静的型(JavaではObject
に似ています)であり、すべての型に対して有効な操作だけがオブジェクト値として受け入れられます。Any
は本当に何が行く意味し、後でであることを名前にそのようなオブジェクトを割り当てる場合でも、型チェッカーは、オブジェクト(のいずれかの使用から外れるながら
object
は、より具体的な型にcastをすることができ型チェック済み)。
list
を受け入れることで、タイプされていないコーナーに関数を描画しました。これは、List[Any]
と同じものになります。型チェック器がそこにあるのを解消しました。戻り値は重要ではなくなりましたが、関数がAny
オブジェクトを含むリストを受け入れるので、適切な戻り値はAny
になります。
タイプチェックされたコードに正しく参加するには、入力チェッカーが戻り値を気にするために入力をList[T]
(一般的にタイプされたコンテナー)としてマークする必要があります。リストから値を取得しているので、あなたの場合はT
になります。 TypeVar
からT
を作成します。
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
は特定の意味で最も制限的なタイプで、値を与えることができます。値が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
は、最も制限の少ないタイプです。可能なメソッドまたは操作は、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
を試してみて、使用する必要があります。たとえば、多くの動的関数や複雑な関数があり、静的にすべての型を入力する時間がない場合は、戻り値の型をAnyに指定して型チェックされた作業に名目上もってきてください。 (あるいは、別の言い方をすると、Anyは、未検証のコードベースを型付きのコードベースに段階的に移行するのに役立つ便利なツールです)。Dict[str, Any]
のタイプを指定するとよいでしょう。対照的に、あなたは価値が文字通り存在のいずれかの可能性のオブジェクトで作業しなければならないことをタイプセーフな方法で示したい場合のためobject
を使用しています。
代わりがない場合を除いて、私は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
機能は、可能な限り最も正確なタイプを返します。
'List [T]'リストが同質であるとは限らないでしょう。 '[None、1、 'foo']'はそのリストに* one *型がないので不正です。容認されたタイプとして 'list'を使うことによって、赤ちゃんは既に入浴水で逃げ出しました。含まれる値には制約は設定されません。 –
@MartijnPieters - 必ずしもそうではない - 'T'は' Any'または 'Union [None、int、str] 'のいずれかに制約される可能性があります。両方の選択肢は '[None、1、 'foo']' typecheckの例になります。しかし、ええ、タイプを 'list'に設定することは、あなたが言ったように' List [Any] 'を実行するのと同じです。 – Michael0x2a
リストが出てきた*他の場所*の宣言は、リストの内容を適切に定義する必要があります。実際にここで制限するほうがはるかに良いと私は同意する。 'Any'は、' get_item() 'の戻り値の後続の使用のために型チェッカーを終了します(戻り値を以前に制約された変数に代入することができます。 –
これは面白いことですが、もう1つの特殊なケースが 'object' /' type'構造体です。もう一度ありがとうMartijn! :) –
残念ながら、これはかなり正しくありません - 下記の私の答えを参照してください。特に重要なのは、 'Any'は完全に制約されないことを意味し、' Any'型の値に対してはすべての操作が許可されます。対照的に、オブジェクトは最も制約の厳しい型です。あなたが 'Any'型の値を持っていれば、' object'インターフェースの一部( '__str__'などのもの)だけが許可されます。 「オブジェクトはAnyのサブクラスであり、その逆もある」は、主に、すべての値が技術的にその型のサブクラスまたはスーパークラスではないにもかかわらず、「Any」と互換性がある理由を説明するために存在します。 – Michael0x2a
@ Michael0x2a:そうですね、入力の観点からは、 'Any''は関数が' object .__ missing__'を使用することを許可しますが、 'object'はそのメソッドはオプションではありません。そのようにして、 '' Any''は、isinstanceテストをちょうど乾かすのではなく、引数がどのように使われるのかを書いています。実際には、 'typing'で使用された' isinstance() 'テストがいずれかの方法で成功するため、2つは同じままです。 –