LoginSignup
2
4

More than 5 years have passed since last update.

isinstance(XXX, type)のtypeってなんだ?

Last updated at Posted at 2017-10-30

unittestパッケージのソースコードリーディングをする中で遭遇したisinstance(XXX, type)について整理します。Pythonのバージョンは3.6.3です。

isinstance関数とは

公式ドキュメントにあるように,あるオブジェクトの型(Class)を判定するときに利用します。

利用例

>>> a = 2
>>> isinstance(a, int)
True
>>> b = [1,2]
>>> isinstance(b, list)
True

unittestでの利用方法

unittestのmain.pyの236行目に以下のコードがあります。

236  if isinstance(self.testRunner, type):

この第2引数に指定されている"type"は何でしょうか。これは上記で示した"int","list"といったクラスではなく,メタクラスと呼ばれるものです。

メタクラスとは?

Pythonのオブジェクトはクラスのインスタンスとして生成されます。また,Pythonではクラスもオブジェクトです。そして,クラスはメタクラスのインスタンスとなります。このため,上記で示したunittestのコードは,"self.testRunner"オブジェクトがtypeのインスタンスであるかどうか,つまりクラスであるかどうかを判定しています。main.py:234行目の上を確認すると,isinstance関数の第1引数である"self.testRunner"にrunner.pyで定義されたTextTestRunnerクラスがif文を満たす場合に代入されることからもそれがわかります。

232  if self.testRunner is None:
233      self.testRunner = runner.TextTestRunner
234  if isinstance(self.testRunner, type):

isinstanceの例からも,そのことがわかります。

>>> isinstance(int, type)
True
>>> isinstance(list, type)
True

Pythonにおけるtypeとは

typeは型を返す組み込み関数として利用するのが一般的ですが,引き数を3つ指定した場合,クラスを生成することができます。

>>> type(list)
<class 'type'>
>>> a = list()
>>> type(a)
<class 'list'>
>>> X = type('X', (object,), dict(a=1))
>>> isinstance(X, type)
True
>>> X.__dict__
mappingproxy({'a': 1, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'X' objects>, '__weakref__': <attribute '__weakref__' of 'X' objects>, '__doc__': None})

>>> class Y(object):
...     a = 1
... 
>>> isinstance(Y, type)
True
>>> Y.__dict__
mappingproxy({'__module__': '__main__', 'a': 1, '__dict__': <attribute '__dict__' of 'Y' objects>, '__weakref__': <attribute '__weakref__' of 'Y' objects>, '__doc__': None})

typeからみれば,すべてのクラスはインスタンスです。これはすべてのクラスの親クラスとなるobjectも例外ではありません。また,type自身もtypeのインスタンスです。

>>> isinstance(object, type)
True
>>>
>>> isinstance(type, type)
True

typeとobjectの関係

typeはメタクラスなので,すべてのクラスのクラスとなります。このため,objectもtypeのインスタンスになりますが,継承関係においては,objectがtypeの親クラスとなります。

>>> issubclass(type, object)
True
>>> issubclass(object, type)
False
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4