この質問は気が遠くなるほど単純なようですが、それを理解することはできません。 Pythonでデータ型をチェックできることはわかっていますが、データ型に基づいて条件を設定するにはどうすればよいですか?たとえば、辞書/リストをソートしてすべての整数を合計するコードを記述する必要がある場合、整数のみを検索するように検索を分離するにはどうすればよいですか?
簡単な例は次のようになると思います:
y = []
for x in somelist:
if type(x) == <type 'int'>: ### <--- psuedo-code line
y.append(x)
print sum(int(z) for z in y)
では、3行目では、このような条件をどのように設定しますか?
いかがですか、
if isinstance(x, int):
しかし、よりクリーンな方法は単に
sum(z for z in y if isinstance(z, int))
TLDR:
if isinstance(x, int):
を使用してください。if type(x) is int:
を使用します。try: ix = int(x)
を使用します。Pythonでの型チェックには、非常に大きな「依存」があります。タイプを処理するには多くの方法があり、すべて長所と短所があります。 Python3では、さらにいくつかが登場しました。
タイプはファーストクラスのオブジェクトであり、他の値と同様に扱うことができます。したがって、何かのタイプをint
に等しくしたい場合は、それをテストします。
_if type(x) is int:
_
これは最も限定的なタイプのテストです。exactタイプの等価性が必要です。多くの場合、これはあなたが望むものではありません:
float
は、多くの目的でint
のように動作しますが、有効ではありません。int
サブクラスまたはenum
は拒否されます。str
またはunicode
のいずれかであり、整数はどちらかint
またはlong
。明示的な型の等価性は、低レベルの操作に使用することに注意してください。
slice
などの一部のタイプはサブクラス化できません。ここでは、明示的なチェックがより明示的です。___class__
_属性に対して比較を実行することもできます。
_if x.__class__ is int:
_
クラスが___class__
_プロパティを定義する場合、これはtype(x)
と同じではないことに注意してください。
チェックするクラスがいくつかある場合は、dict
を使用してアクションをディスパッチする方が拡張性が高く、明示的なチェックよりも高速(5〜10タイプ)になります。これは、変換とシリアル化に特に役立ちます。
_dispatch_dict = {float: round, str: int, int: lambda x: x}
def convert(x):
converter = self.dispatch_dict[type(x)] # lookup callable based on type
return converter(x)
_
慣用型テストではisinstance
builtin を使用します:
_if isinstance(x, int):
_
このチェックは正確かつ高性能です。これは、ほとんどの場合、タイプをチェックするために欲しいものです:
int
サブクラスはこのテストに合格します。isinstance(x, (int, long))
を実行すると、すべての組み込み整数が得られます。最も重要なのは、マイナス面がほとんどの場合無視できることです。
Tuple
)またはさらにはisinstance(x, list)
をチェックしますiterable(例えばgenerator
)も同様です。これは、スクリプトやアプリケーションよりも、汎用ライブラリの方が重要です。タイプがすでにある場合、issubclass
は同じように動作します。
_if issubclass(x_type, int):
_
Pythonには 抽象基本クラス の概念があります。大まかに言えば、これらは型の意味ではなく、型の意味を表しています。
_if isinstance(x, numbers.Real): # accept anything you can sum up like a number
_
つまり、type(x)は必ずしも_numbers.Real
_からinheritとは限りませんが、behaveいいね。それでも、これは非常に複雑で難しい概念です。
int
です。ただし、汎用ライブラリや抽象化には非常に役立ちます。
dict
は特定のメモリ内タイプに制限します。対照的に、_collections.abc.Mapping
_には、データベースラッパー、大容量のディスクバックアップ辞書、レイジーコンテナーなども含まれます-およびdict
。collections.abc.Iterable
_に対してチェックすると、それらはすべてfor
ループで機能します。通常、使い捨てのスクリプトには必要ありませんが、数個のpythonリリースを超えて存在するものすべてに使用することを強くお勧めします。
型を処理する慣用的な方法は、型をテストすることではなく、互換性があると想定することです。入力に誤った型がすでにあると予想される場合は、互換性のないものはすべてスキップしてください。
_try:
ix = int(x)
except (ValueError, TypeError):
continue # not compatible with int, try the next one
else:
a.append(ix)
_
これは実際には型チェックではありませんが、通常同じ目的を果たします。
float
をint
に特化しています。int
に準拠しているかを知らなくても機能します。主な欠点は、それが明示的な変換であることです。
str
を変換します。float
からint
は、数値だけが必要な場合に使用します。変換は、いくつかの特定のユースケースに効果的なツールです。入力が何であるかを大まかに知っていて、出力について保証しなければならない場合に最適です。
型チェックの目的は、適切な関数を選択することだけである場合があります。この場合、 _functools.singledispatch
_ などの関数ディスパッチにより、特定のタイプの関数実装を特殊化できます。
_@singledispatch
def append_int(value, sequence):
return
@append_int.register
def _(value: int, sequence):
sequence.append(value)
_
これはisinstance
とdict
ディスパッチの組み合わせです。これは、より大きなアプリケーションに最も役立ちます。
それでも、それには欠点がないわけではありません。
dict
ルックアップよりも遅くなります。最善の策は、そもそもタイプをチェックする必要がないようにすることです。ユースケースに強く依存するため、これは少しメタトピックです。
ここでは、somelist
のソースに非数値を入れるべきではありません。
int型の変数xを宣言しましょう
x = 2
if type(x) == type(1) or isinstance(x, int):
# do something
どちらも正常に動作します。