1. ホーム
  2. パイソン

[解決済み】type()とisinstance()の違いは何ですか?)

2022-03-18 14:23:30

質問

この2つのコード・スニペットの違いは何ですか?

使用方法 type() :

import types

if type(a) is types.DictType:
    do_something()
if type(b) in types.StringTypes:
    do_something_else()

使用方法 isinstance() :

if isinstance(a, dict):
    do_something()
if isinstance(b, str) or isinstance(b, unicode):
    do_something_else()

解決方法は?

他の(すでに良い!)回答の内容を要約すると。 isinstance は継承に対応します(派生クラスのインスタンスは のインスタンスであることを確認し、同時に type はそうではありません(型の同一性を要求し、サブタイプ(別名サブクラス)のインスタンスは拒否します)。

通常、Pythonでは、もちろん継承をサポートしたコードにしたいので(継承はとても便利なので、自分のコードを使うのを止めるのはまずい!)、そのために isinstance の同一性をチェックするよりも、より悪いことではありません。 type は、継承をシームレスにサポートするからです。

というわけではなく isinstance 良い ただ 悪くない 型の等質性をチェックするよりも。 通常の、Pythonicな、好ましい解決策は、ほとんど必ず "ダックタイピング":引数を使ってみてください。 あたかも を指定し、それを try / except 文は、引数が実際にはその型(あるいはそれをうまく模倣した他の型;-)でなかった場合に発生しうるすべての例外を捕らえ、そして except 節で、(あたかも他の型であるかのように)他のことを試してみてください。

basestring しかし、かなり特殊なケースで、組み込み型が存在し のみ を使用することができます。 isinstance (両方とも strunicode サブクラス basestring ). 文字列はシーケンスですが(ループ、インデックス、スライスなど)、一般的にはスカラー型として扱いたいものです。すべての種類の文字列(および他のスカラー型、つまりループできないもの)をある方法で扱い、すべてのコンテナ(リスト、セット、ディクテなど)を別の方法で扱うのは、やや不都合(ただし、使用頻度は高い)ですし basestring プラス isinstance このイディオムの全体的な構成は次のようなものです。

if isinstance(x, basestring)
  return treatasscalar(x)
try:
  return treatasiter(iter(x))
except TypeError:
  return treatasscalar(x)

と言うことができます。 basestring 抽象ベースクラス ("ABC") - サブクラスに対して具体的な機能を提供せず、むしろマーカーとして存在し、主に isinstance . このコンセプトは明らかにPythonで成長しているものです。 PEP 3119 を一般化したものが受け入れられ、Python 2.6と3.0から実装されています。

このPEPでは、ABCがダックタイピングの代わりになることはよくあるが、一般的に大きな圧力はないことを明確にしている(以下、「ダックタイピング」という。 こちら ). しかし、最近のPythonのバージョンで実装されているABCは、特別な良さを提供します。 isinstance (そして issubclass のインスタンス)以上の意味を持つようになりました(特に、任意のクラスをABCに登録することで、サブクラスとして表示し、そのインスタンスをABCのインスタンスとして表示することができます)。また、ABCは、テンプレート・メソッド設計パターンのアプリケーションによって、実際のサブクラスに非常に自然な方法で利便性を提供できます(詳細は ここで こちら TM DPについては、一般的に、特にPythonにおいて、ABCとは無関係に、[[part II]]で詳しく説明しています)。

Python 2.6で提供されるABCサポートの基本的な仕組みは、以下を参照してください。 こちら 3.1版については、非常によく似ているので、以下を参照してください。 こちら . どちらのバージョンでも、標準ライブラリモジュール コレクション (これは3.1バージョンです。よく似た2.6バージョンについては こちら ) は、いくつかの便利なABCを提供しています。

この回答では、ABCについて(TM DPの機能が、Pythonの古典的な選択肢である、以下のようなmixinクラスと比較して、間違いなくより自然な配置であることを除いて)重要なことを保持します。 ユーザー辞書.ディクティミクシン を作成することです。 isinstance (そして issubclass ) は、以前 (2.5以前) よりもずっと魅力的で広く普及しており、したがって、対照的に、最近のPythonバージョンでは、型の等質性をチェックすることが、以前よりもさらに悪い習慣になっています。