2016-10-02 14 views

答えて

7

はい、違いがあります。 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 type documentationより:

より正確なタイプにタイプ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] 
+0

これは面白いことですが、もう1つの特殊なケースが 'object' /' type'構造体です。もう一度ありがとうMartijn! :) –

+0

残念ながら、これはかなり正しくありません - 下記の私の答えを参照してください。特に重要なのは、 'Any'は完全に制約されないことを意味し、' Any'型の値に対してはすべての操作が許可されます。対照的に、オブジェクトは最も制約の厳しい型です。あなたが 'Any'型の値を持っていれば、' object'インターフェースの一部( '__str__'などのもの)だけが許可されます。 「オブジェクトはAnyのサブクラスであり、その逆もある」は、主に、すべての値が技術的にその型のサブクラスまたはスーパークラスではないにもかかわらず、「Any」と互換性がある理由を説明するために存在します。 – Michael0x2a

+0

@ Michael0x2a:そうですね、入力の観点からは、 'Any''は関数が' object .__ missing__'を使用することを許可しますが、 'object'はそのメソッドはオプションではありません。そのようにして、 '' Any''は、isinstanceテストをちょうど乾かすのではなく、引数がどのように使われるのかを書いています。実際には、 'typing'で使用された' isinstance() 'テストがいずれかの方法で成功するため、2つは同じままです。 –

5

Anyobjectは、表面的に似ていますが、実際には、完全な意味での反対です。

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)) 

あなたは、一般的にのみコードを入力一緒にダイナミックで静的に混合する方法として...

  1. 例のためAnyを試してみて、使用する必要があります。たとえば、多くの動的関数や複雑な関数があり、静的にすべての型を入力する時間がない場合は、戻り値の型をAnyに指定して型チェックされた作業に名目上もってきてください。 (あるいは、別の言い方をすると、Anyは、未検証のコードベースを型付きのコードベースに段階的に移行するのに役立つ便利なツールです)。
  2. 型入力が難しい式に型を与える方法。たとえば、Pythonの型アノテーションは現在、再帰型をサポートしていないため、任意のJSONディクテーションのような型指定が難しくなります。一時的な対策として、JSON辞書に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機能は、可能な限り最も正確なタイプを返します。

+0

'List [T]'リストが同質であるとは限らないでしょう。 '[None、1、 'foo']'はそのリストに* o​​ne *型がないので不正です。容認されたタイプとして 'list'を使うことによって、赤ちゃんは既に入浴水で逃げ出しました。含まれる値には制約は設定されません。 –

+0

@MartijnPieters - 必ずしもそうではない - 'T'は' Any'または 'Union [None、int、str] 'のいずれかに制約される可能性があります。両方の選択肢は '[None、1、 'foo']' typecheckの例になります。しかし、ええ、タイプを 'list'に設定することは、あなたが言ったように' List [Any] 'を実行するのと同じです。 – Michael0x2a

+0

リストが出てきた*他の場所*の宣言は、リストの内容を適切に定義する必要があります。実際にここで制限するほうがはるかに良いと私は同意する。 'Any'は、' get_item() 'の戻り値の後続の使用のために型チェッカーを終了します(戻り値を以前に制約された変数に代入することができます。 –

関連する問題