Pythonでオブジェクトのタイプを比較する方法は?


163

基本的に私はこれをやりたいです:

obj = 'str'
type ( obj ) == string

私は試した:

type ( obj ) == type ( string )

そしてそれはうまくいきませんでした。

また、他のタイプはどうですか?たとえば、複製できませんでしたNoneType


これは機能しますtype(obj) == str
Joshua Varghese

回答:


241
isinstance()

あなたの場合、isinstance("this is a string", str)返却しTrueます。

これを読むこともできます:http : //www.canonical.org/~kragen/isinstance/


4
私はあなた(OP)が参照されたリンクを必ず読むべきだと思います。これは、オブジェクトのタイプをチェックすることが通常悪い考えである理由の多くの詳細と、代わりに何をすべきかについての多くの詳細を与えます。
ジェフシャノン

2
strではなくbasestrを使用する必要があります。それ以外の場合は、Unicodeを選択しません。(ただし3.xではstr basestr だと思います)
hasen

36

isinstance 作品:

if isinstance(obj, MyClass): do_foo(obj)

ただし、注意してください。アヒルのように見え、アヒルのように聞こえる場合は、アヒルです。

編集:なしタイプの場合、あなたは単に行うことができます:

if obj is None: obj = MyClass()

def distance_from_zero(n): if isinstance(n,int) or isinstance(n,float): return abs(n) else: return "Nope" print distance_from_zero(True) これは、「Nope」の代わりに「1」を返します。これを回避する方法は?
dig_123

使用したいが、isinstanceそれでもチェックしたい場合Noneisinstance(obj, (MyClass, type(None)))動作します。types.NoneTypePython 3から削除されtype(None)たため、への参照を取得するほど移植性がありませんNoneType
Santeri Paavolainen 2016

33

まず、すべての型の比較を避けます。それらは非常に、非常にまれに必要です。まれに、関数内のパラメーターの型を確認するのに役立つ場合があります。間違ったタイプのデータは例外を発生させます。

基本的な変換関数はすべて、type関数と同じようにマッピングされます。

type(9) is int
type(2.5) is float
type('x') is str
type(u'x') is unicode
type(2+3j) is complex

他にもいくつかのケースがあります。

isinstance( 'x', basestring )
isinstance( u'u', basestring )
isinstance( 9, int )
isinstance( 2.5, float )
isinstance( (2+3j), complex )

なし、ちなみに、この種の型チェックは必要ありません。NoneはNoneTypeの唯一のインスタンスです。Noneオブジェクトはシングルトンです。なしを確認してください

variable is None

ところで、一般的には上記を使用しないでください。通常の例外とPython独自の自然な多態性を使用します。


3
DSLからの入力を検証する場合は、これらすべてが必要になりますNoneType。パラメータは何をすることができた場合strunicodeまたはNoneisinstance(x, (str, unicode, types.NoneType))をチェックするよりもはるかにクリーンですNone。遅延計算用のツールを構築している場合、またはリソースを大量に消費する長いプロセスを起動しようとしている場合はtype、カスタム検証手順の間にエラーを事前に検出することが重要です。これは、これまで取り組んできたほとんどすべての科学計算プロジェクトの重要な部分です。私が見たすべての開発プロジェクトのうち、これを必要としていない人よりも多くの人がこれを必要としています。
ely

23

他のタイプについては、タイプモジュールを確認してください。

>>> import types
>>> x = "mystring"
>>> isinstance(x, types.StringType)
True
>>> x = 5
>>> isinstance(x, types.IntType)
True
>>> x = None
>>> isinstance(x, types.NoneType)
True

PSタイプチェックは悪い考えです。


15

あなたはいつでもtype(x) == type(y)トリックを使うことができyます。

# check if x is a regular string
type(x) == type('')
# check if x is an integer
type(x) == type(1)
# check if x is a NoneType
type(x) == type(None)

多くの場合、特に最近のpythonでは、これを行うためのより良い方法があります。しかし、1つだけ覚えておきたい場合は、それを覚えておくことができます。

この場合、より良い方法は次のとおりです。

# check if x is a regular string
type(x) == str
# check if x is either a regular string or a unicode string
type(x) in [str, unicode]
# alternatively:
isinstance(x, basestring)
# check if x is an integer
type(x) == int
# check if x is a NoneType
x is None

最後のケースに注意してください:NoneTypePythonのインスタンスは1つしかありません。None。です。NoneTypeは例外で多く見られます(TypeError: 'NoneType' object is unsubscriptable-いつも私に起こります...)。しかし、コードでそれを参照する必要はほとんどありません。

最後に、fengshaunが指摘しているように、Pythonでの型チェックは必ずしも良い考えではありません。あたかもそれが期待するタイプであるかのように値を使用し、その結果生じる例外をキャッチ(または伝搬を許可)する方が、よりpythonicです。


1
価値があるのは、Pythonで型をチェックする方法としてisinstance()を使用することです(必要な場合)。
David Z

6

あなたはとても近いです!string型ではなくモジュールです。objのタイプを文字列のタイプオブジェクトと比較したい、つまりstr

type(obj) == str  # this works because str is already a type

または:

type(obj) == type('')

Python 2ではobj、Unicodeタイプの場合、上記のどちらも機能しません。もしないだろうisinstance()。これを回避する方法については、この投稿へのJohnのコメントを参照してください...私はこれを約10分間覚えようとしていましたが、メモリブロックがありました!


2
isinstance()でbasestringを使用して、strとunicodeの両方を取得します。
John Fouhy

5

あなたが書かなければならないからです

s="hello"
type(s) == type("")

typeはインスタンスを受け入れ、そのタイプを返します。この場合、2つのインスタンスのタイプを比較する必要があります。

プリエンプティブチェックを実行する必要がある場合は、タイプよりもサポートされているインターフェイスをチェックする方が適切です。

同じインターフェイスを実装しているため完全に問題のない完全に異なる型の別のインスタンスが存在する可能性があるにもかかわらず、コードは特定の型のインスタンスを必要とするという事実を除けば、型は実際にはあまりわかりません。

たとえば、次のコードがあるとします

def firstElement(parameter):
    return parameter[0]

ここで、次のように考えたとします。このコードではタプルのみを受け入れます。

import types

def firstElement(parameter):
    if type(parameter) != types.TupleType:
         raise TypeError("function accepts only a tuple")
    return parameter[0]

これにより、このルーチンの再利用性が低下しています。リスト、文字列、またはnumpy.arrayを渡した場合は機能しません。より良いものは

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    return parameter[0]

しかし、それを行う意味はありません。parameter[0]は、プロトコルが満たされていない場合に例外を発生させます...もちろん、これは、副作用を回避したり、失敗する前に呼び出すことができる呼び出しから回復したりする必要がある場合を除きます。(愚かな)例、要点を述べるだけです:

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    os.system("rm file")
    return parameter[0]

この場合、コードはsystem()呼び出しを実行する前に例外を発生させます。インターフェースチェックがなければ、ファイルを削除してから例外を発生させることになります。


インターフェイスを確認するための実際の推奨方法を示していただきありがとうございます。ここでの回答の多くはそれについて言及していますが、代わりに何が良いかを示す例はほとんどありません。それでも私の個人的な質問には直接回答しません(意味のあるアイテムを多く含む文字列のリストを、意味のないアイテムを多く含む文字列から分離しようとしています。ありがとう
Nick

5

文字列の代わりにstrを使用

type ( obj ) == str

説明

>>> a = "Hello"
>>> type(a)==str
True
>>> type(a)
<type 'str'>
>>>

4

私が使う type(x) == type(y)

たとえば、何かを確認したい場合は配列です:

type( x ) == type( [] )

文字列チェック:

type( x ) == type( '' ) or type( x ) == type( u'' )

Noneに対してチェックしたい場合は、

x is None

え?なぜそれが一般的に悪い考えなのですか?文字列には、strとunicodeの2つのタイプがあるため、文字列(3.0より前のバージョン)には悪い考えです。配列の場合、それは私見です。
09

@hasen:全体的に悪い考えです。配列のように動作するが、たとえばデータベースから値をフェッチする独自の型を定義するとどうなりますか?あなたのコードは理由もなく私のタイプで失敗します。
nosklo 2009

@hasen:voltronwによる、最も投票された(+7)回答のリンクcanonical.org/~kragen/isinstanceを読む
nosklo

1
さて、型をチェックする理由(少なくとも私にとっては)は、配列を他の型(配列を模倣する型を含む)とは異なる方法で扱いたいからです。
hasen

2
あなたが間違っている。具体的な例を挙げましょう。djangoには、文字列または文字列の配列を受け入れることができるテンプレートレンダリングのショートカットがあります。現在、文字列と配列(リスト)の両方が反復可能ですが、この場合、関数はそれらを区別する必要があります。
hasen



2

タイプを取得するには、次のように__class__メンバーを使用しますunknown_thing.__class__

ダックタイピングの話は完全に良い質問には答えないので、ここでは役に立たない。アプリケーションコードでは、何かのタイプを知る必要はありませんが、オブジェクトのタイプを学習する方法があると便利です。ユニットテストを検証するために、実際のクラスを取得する必要がある場合があります。可能なすべてのオブジェクトが同じAPIを持っているため、ダックのタイピングはそこで邪魔になりますが、正しいのは1つだけです。また、他の人のコードを保守していることもあり、渡されたオブジェクトの種類がわかりません。これは、Pythonのような動的に型付けされる言語に関する私の最大の問題です。バージョン1は、開発が非常に簡単で迅速です。バージョン2は、特にバージョン1を作成しなかった場合は、バンズの苦痛です。そのため、作成していない関数を操作しているときに、パラメーターのタイプを知る必要がある場合があります。

ここで__class__パラメータが役立ちます。それが(私が知る限り)オブジェクトのタイプを取得する最良の方法(おそらく唯一の方法)です。


2

を使用しisinstance(object, type)ます。上記のように、正しいを知っている場合type、これは簡単に使用できます。たとえば、

isinstance('dog', str) ## gives bool True

しかし、より難解なオブジェクトの場合、これは使いにくい場合があります。例えば:

import numpy as np 
a = np.array([1,2,3]) 
isinstance(a,np.array) ## breaks

しかし、あなたはこのトリックを行うことができます:

y = type(np.array([1]))
isinstance(a,y) ## gives bool True 

私は(変数インスタンスをお勧めしますので、yチェックしたいオブジェクトのタイプでこの場合は)(例えば、type(np.array()))、そして使用isinstance


0

クラスをチェックレベルで比較できます。

#!/usr/bin/env python
#coding:utf8

class A(object):
    def t(self):
        print 'A'
    def r(self):
        print 'rA',
        self.t()

class B(A):
    def t(self):
        print 'B'

class C(A):
    def t(self):
        print 'C'

class D(B, C):
    def t(self):
        print 'D',
        super(D, self).t()

class E(C, B):
    pass

d = D()
d.t()
d.r()

e = E()
e.t()
e.r()

print isinstance(e, D) # False
print isinstance(e, E) # True
print isinstance(e, C) # True
print isinstance(e, B) # True
print isinstance(e, (A,)) # True
print e.__class__ >= A, #False
print e.__class__ <= C, #False
print e.__class__ <  E, #False
print e.__class__ <= E  #True
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.