変数がクラスかどうかを確認するにはどうすればよいですか?


236

変数がクラス(インスタンスではない!)かどうかを確認する方法を考えていました。

isinstance(object, class_or_type_or_tuple)これを行うために関数を使用しようとしましたが、クラスがどのような型になるかわかりません。

たとえば、次のコードでは

class Foo: pass  
isinstance(Foo, **???**) # i want to make this return True.

class」を???に置き換えてみました 、しかし私はそれclassがpythonのキーワードであることを認識しました。

回答:


335

さらに良い: inspect.isclass関数をます。

>>> import inspect
>>> class X(object):
...     pass
... 
>>> inspect.isclass(X)
True

>>> x = X()
>>> isinstance(x, X)
True
>>> y = 25
>>> isinstance(y, X)
False

7
検査するオブジェクトがクラスインスタンスである場合にもinspect.isclass戻るにTrueは、inspect.isclass(type(Myclass()))
michaelmeyer

8
何より:)?
Mad Physicist

8
@michaelmeyerはtype(whatever)常にクラスであるオブジェクトを返すため、このチェックは冗長です。そうしないwhateverと、インスタンス化する方法がないため、そもそもチェックを実行できません。
a_guest

うまくいきません。snakemakeでpython3を使用すると、type(snakemake.utils)が返されますが<class 'module'>、がinspect.isclass(snakemake.utils)返されますFalse
2018

3
それsnakemake.utilはモジュールがクラスではないからですか?
ベンジャミンピーターソン

44

inspect.isclassはおそらく最良のソリューションであり、実際にどのように実装されているかを確認するのは非常に簡単です。

def isclass(object):
    """Return true if the object is a class.

    Class objects provide these attributes:
        __doc__         documentation string
        __module__      name of module in which this class was defined"""
    return isinstance(object, (type, types.ClassType))

5
覚えているimport types
グエン

13
types.ClassTypePython 3では不要になりました(削除されました)。
kawing-chiu 2016

これは、Python 2でも新しいスタイルクラスではまったく機能しません。...このソリューションだけを使用しないでください
Erik Aronesty

それはinspectモジュールから取られたので、それが機能しないのではないかと思います。たとえば、Python2.7で確認するのは簡単ですIn [8]: class NewStyle(object): ...: pass ...: In [9]: isinstance(NewStyle, (type, types.ClassType)) Out[9]: True
andrea_crotti

これはPython 2の実装で、古いスタイルと新しいスタイルのクラスを処理する必要があります。Python 3はこれをに単純化しisinstance(object, type)ます。オブジェクトが好き。なおintliststr、などがある、あなたが間を区別するためにこれを使用することはできませんので、クラスカスタムクラスPythonで定義される、組み込みのCコードで定義されたクラス
Martijn Pieters

39
>>> class X(object):
...     pass
... 
>>> type(X)
<type 'type'>
>>> isinstance(X,type)
True

1
うーん...いい答えですが、私のFooクラスでtype(Foo)を実行すると、<type 'type'>ではなく<type 'classobj'>と表示されます。Xがオブジェクトから継承しているという事実に違いがあると思いますが、Fooはそうではありません。これから生じる他の違いはありますか?ありがとう。
jeeyoungk 2008

6
これは、古いスタイルのクラスでは動作しません:'class Old:pass' 'isinstance(Old, type) == False'、しかしinspect.isclass(Old) == True
jfs 2008

1
@jeeyoungk:「違いは...から来ると仮定する」のではなく、実際にコードでそれを読んでいます。オブジェクトのサブクラス(「新しいスタイル」)には、ここに表示されているとおりの目的のプロパティがあります。
S.Lott、2008

12
ヒントは次のとおりです。これは新しいスタイルのクラスで機能するため、古いスタイルのクラスを使用しないでください。古いスタイルのクラスを使用しても意味がありません。
S.Lott、2008

isinstance(e、f)Eはインスタンス化されたオブジェクト、Fはクラスオブジェクトです。
デクスター

24
isinstance(X, type)

クラスの場合とそうでないTrue場合に戻ります。XFalse


3
Xがクラスであっても、Falseを受け取ります。
Mads Skjern

6
これは新しいスタイルクラスでのみ機能します。古いスタイルのクラスは「classobj」タイプです。したがって、古いスタイルのクラスを使用している場合は、次のことを実行できます。import type isinstance(X、types.ClassType)
Charles L.

2
これS. Lott's answerは、4年古いと同じように見えます。
イーサンファーマン2017年

5

このチェックは、Python 2.xとPython 3.xの両方と互換性があります。

import six
isinstance(obj, six.class_types)

これは基本的に、andrea_crotti回答と同じチェックを実行するラッパー関数です。

例:

>>> import datetime
>>> isinstance(datetime.date, six.class_types)
>>> True
>>> isinstance(datetime.date.min, six.class_types)
>>> False


1

最も簡単な方法はinspect.isclass、最も投票された回答に投稿されたとおりに使用することです。
実装の詳細はpython2 inspectpython3 inspectにあります。
新しいスタイルのクラスの場合:isinstance(object, type)
古いスタイルのクラスの場合:isinstance(object, types.ClassType)
em、古いスタイルのクラスの場合はを使用しtypes.ClassTypeています。types.pyのコードは次のとおりです。

class _C:
    def _m(self): pass
ClassType = type(_C)

1

ベンジャミン・ピーターソンはinspect.isclass()この仕事のための使用について正しいです。ただし、組み込み関数issubclassを使用して、Classオブジェクトが特定Classであるかどうか、したがって暗黙的にa Classであるかどうかをテストできることに注意してください。ユースケースによっては、これはもっとpythonicになる場合があります。

from typing import Type, Any
def isclass(cl: Type[Any]):
    try:
        return issubclass(cl, cl)
    except TypeError:
        return False

その後、次のように使用できます。

>>> class X():
...     pass
... 
>>> isclass(X)
True
>>> isclass(X())
False

-2

ここにはすでにいくつかの実用的な解決策がありますが、ここに別の解決策があります:

>>> import types
>>> class Dummy: pass
>>> type(Dummy) is types.ClassType
True

types.ClassTypePython 3で削除されました
Beau Barker
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.