Pythonは、インスタンスがリスト内のタイプであるかどうかをチェックしますか?


90

どうすればpythoniclyを行うことができますか?

var = 7.0
var_is_good = isinstance(var, classinfo1) or isinstance(var, classinfo2) or isinstance(var, classinfo3) or ... or  isinstance(var, classinfoN)

classinfoのリストを渡すことができないのはばかげているようです。

var_is_good = isinstanceofany( var, [classinfo1, classinfo2, ... , classinfoN] )

では、isinstanceofany機能は何ですか?


それが数のように加算され、数のように減算され、数のように乗算される場合...なぜそれが数であるかを知る必要があるのですか?詳細については、ダックタイピングを参照してください。

私の特定のユースケースは、(を返す関数(またはnumbersympy式を返すOR)を返す関数を持つことです。生成した関数が、他の関数に渡すときに想定どおりに機能することを確認したいと思います。
D・アダムス

関数が同種のものを返さないのはなぜですか?それがここの匂いです。ダックタイピングで速くて緩くなることができますが、あなたはあなたが返すものに一貫しているべきです。

数値に評価されることもあれば、変数が内部に残っていることもあるsympy式をいつでも返すことができると思います。
D・アダムス

それがあなたがここでやりたいと思っていることです。複数の異なる型を返す代わりに、1つの型を返し、必要に応じて、数に減らします。

回答:


200

isinstance()2番目の引数のクラスのタプルを取ります。最初の引数がそのシーケンスのいずれかのタイプのインスタンスである場合、trueを返します。

isinstance(var, (classinfo1, classinfo2, classinfo3))

言い換えれば、箱から出して、isinstance() すでにこの機能を提供しいます。

isinstance()ドキュメントから:

classinfoがクラスオブジェクトでもタイプオブジェクトでもない場合は、クラスまたはタイプオブジェクトのタプルであるか、他のそのようなタプルを再帰的に含むことができます(他のシーケンスタイプは受け入れられません)。

強調鉱山; 再帰的な性質に注意してください。(classinfo1, (classinfo2, classinfo3))も有効なオプションです。


12

あなたはすでにあなたの質問のタイトルにかなり近かった。使用できるanyリスト:

var = 7.0
var_is_good = any([isinstance(var, classinfo1),
                   isinstance(var, classinfo2),
                   isinstance(var, classinfo3), ...
                   isinstance(var, classinfoN)])

しかし、のドキュメントを見ると、次のisinstanceことが明らかになります。

object引数がclassinfo引数、またはその(直接、間接、または仮想)サブクラスのインスタンスである場合はtrueを返します。オブジェクトが指定されたタイプのオブジェクトでない場合、関数は常にfalseを返します。classinfoがクラス(型オブジェクト)でない場合は、型オブジェクトのタプルであるか、他のそのようなタプルを再帰的に含む可能性があります(他のシーケンスタイプは受け入れられません)。classinfoがタイプまたはタイプのタプルではなく、そのようなタプルである場合、TypeError例外が発生します。

これはそれを行うためのより良い方法が

var = 7.0
var_is_good = isinstance(var, (classinfo1,
                               classinfo2,
                               classinfo3,
                               ...,
                               classinfoN))

2
変更isinstanceだけで繰り返すclassinfoことは、私にはあまりPythonicではないようです。

1
試してみてください var.__class__。それはあなたが望むものですか?@マコト:同意します。Pythonicではありません!
フラメンコ

@マコトうん。しかし、それはDAdamsがドキュメントで「any」を検索することで簡単に見つけられたものでした。私は自分の答えをより良いバージョンに拡張しました...しかし明らかにMartijnPietersはより高速でした...もう一度。
マーティントーマ

3
any()リスト付きは..無意味です。を使用する必要がある場合は、ジェネレータ式を使用してください。any()少なくとも、早期終了のメリットが得られます。
MartijnPieters

isinstanceタプル付きが進むべき道だと思います。any彼がタイトルで求めているもののようだったので、私は解決策について言及したかっただけです。
マーティントーマ2015年

4

これはあなたの問題を解決します:

valid_instance_types = <tuple of types you want to allow>
var_is_good = isinstance(var, valid_instance_types)

ドキュメントに基づいて、タイプの値をに渡す方法はたくさんありますisinstance

これがほんの一部であるより複雑な検証を行おうとしている場合は、官能的なものを調べることもできます。


でisinstance()は既に第二引数としてチェックするために必要なすべての種類のタプルを渡し、この機能を提供しています
RFV

@ RFV5sはい....それが私がここで提供した例が示していることです。あなたの異議は何ですか?
ナサニエルフォード

1

通常はを使用するべきではありませんがisinstance、やりたいことはany()組み込み関数を使用して実行できます。

var_is_good = any(isinstance(var, t) for t in [type1, type2, type3])

7
これはやり過ぎです。isinstance()を使用せずに、すぐに使用できる機能を提供しますany()
MartijnPieters

@MartijnPieters isinstanceが複数のタイプをとることができることに気づいていませんでしたが、質問は「特定の関数からの戻り値があるかどうかを確認するにはどうすればよいですか?異なるパラメータを使用するとtrueになります」
Chad S.

使うべきかどうかisinstance()は関係ありません。
RFV

@ChadS。なぜ彼は使うべきではないと思いますisinstance()か?ありがとうございました。
idature

Pythonは型チェックを避けているからです。それはほとんど利益のために多くの余分なコード(そしてCPUサイクル)です。ダックタイピングが推奨されます。
チャド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.