3. データモデル

3.1. オブジェクト、値、および型

Python における オブジェクト (object) とは、データを抽象的に表したものです。Python プログラムにおけるデータは全て、オブジェクトまたはオブジェクト間の関係として表されます。(ある意味では、プログラムコードもまたオブジェクトとして表されます。これはフォン・ノイマン: Von Neumann の “プログラム記憶方式コンピュータ: stored program computer” のモデルに適合します。)

すべての属性は、同一性 (identity)、型、値をもっています。 同一性 は生成されたあとは変更されません。これはオブジェクトのアドレスのようなものだと考えられるかもしれません。 ‘is‘ 演算子は2つのオブジェクトの同一性を比較します。 id() 関数は同一性を表す整数を返します。

CPython では、 id(x)x が格納されているメモリ上のアドレスを返します。

オブジェクトの型はオブジェクトがサポートする操作 (例: len() をサポートするか) と、オブジェクトが取りうる値を決定します。 type() 関数はオブジェクトの型 (型自体もオブジェクトです) を返します。 同一性と同じく、オブジェクトの型(type) も変更不可能です。 [1]

オブジェクトによっては を変更することが可能です。 値を変更できるオブジェクトのことを mutable と呼びます。 生成後に値を変更できないオブジェクトのことを immutable と呼びます。 (mutable なオブジェクトへの参照を格納している immutableなコンテナオブジェクトの値は、その格納しているオブジェクトの値が変化した時に変化しますが、コンテナがどのオブジェクトを格納しているのかが変化しないのであれば immutable だと考えることができます。 したがって、 immutable かどうかは値が変更可能かどうかと完全に一致するわけではありません) オブジェクトが mutable かどうかはその型によって決まります。 例えば、数値型、文字列型とタプル型のインスタンスは immutable で、 dict や list は mutable です。

オブジェクトを明示的に破壊することはできません; しかし、オブジェクトに到達不能 (unreachable) になると、ガベージコレクション (garbage-collection) によって処理されます。実装では、ごみ収集を遅らせたり、全く行わないようにすることができます — 到達可能なオブジェクトをごみ収集処理してしまわないかぎり、どう実装するかは実装品質の問題です。

現在の CPython 実装では参照カウント(reference-counting) 方式を使っており、(オプションとして) 循環参照を行っているごみオブジェクトを遅延検出します。この実装ではほとんどのオブジェクトを到達不能になると同時に処理することができますが、循環参照を含むごみオブジェクトの収集が確実に行われるよう保証しているわけではありません。循環参照を持つごみオブジェクト収集の制御については、 gc モジュールを参照してください。 CPython以外の実装は別の方式を使っており、CPythonも将来は別の方式を使うかもしれません。オブジェクトが到達不能になったときに即座に終了処理されることに頼らないでください (例えば、ファイルは必ず閉じてください)。

実装のトレース機能やデバッグ機能を使えば、通常は収集されてしまうようなオブジェクトを生かしておくことがあるので注意してください。また、 ‘try...except‘ 文を使って例外を捕捉できるようにすると、オブジェクトを生かしておくことがあります。

オブジェクトには、開かれたファイルやウィンドウといった、 “外部 (external) の” リソースへの参照を含むものがあります。これらのリソースは、オブジェクトがごみ収集された際に解放されるものと理解されていますが、ごみ収集が行われる保証はないので、こうしたオブジェクトは外部リソースを明示的に解放する方法、大抵は close() メソッドも提供しています。こうしたオブジェクトは明示的に close するよう強く奨めます。この操作をする際には、’try...finally‘ 文や、 ‘with‘ 文を使うと便利です。

他のオブジェクトに対する参照をもつオブジェクトもあります; これらは コンテナ (container) と呼ばれます。コンテナオブジェクトの例として、タプル、リスト、および辞書が挙げられます。オブジェクトへの参照自体がコンテナの値の一部です。ほとんどの場合、コンテナの値というと、コンテナに入っているオブジェクトの値のことを指し、それらオブジェクトのアイデンティティではありません; しかしながら、コンテナの変更可能性について述べる場合、今まさにコンテナに入っているオブジェクトのアイデンティティのことを指します。したがって、 (タプルのように) 変更不能なオブジェクトが変更可能なオブジェクトへの参照を含む場合、その値が変化するのは変更可能なオブジェクトが変更された時、ということになります。

型はオブジェクトの動作のほとんど全てに影響します。オブジェクトのアイデンティティが重要かどうかでさえ、ある意味では型に左右されます: 変更不能な型では、新たな値を計算するような操作を行うと、実際には同じ型と値を持った既存のオブジェクトへの参照を返すことがありますが、変更可能なオブジェクトではそのような動作は起こりえません。例えば、 a = 1; b = 1 とすると、 ab は値 1 を持つ同じオブジェクトを参照するときもあるし、そうでないときもあります。これは実装に依存します。しかし、 c = []; d = [] とすると、 cd はそれぞれ二つの異なった、互いに一意な、新たに作成された空のリストを参照することが保証されています。 (c = d = [] とすると、 cd の両方に同じオブジェクトを代入します)

3.2. 標準型の階層

以下は Python に組み込まれている型のリストです。(実装によって、C、Java、またはその他の言語で書かれた) 拡張モジュールで、その他の型が定義されていることがあります。新たな型 (有理数や、整数を効率的に記憶する配列、など) の追加は、たいてい標準ライブラリを通して提供されますが、将来のバージョンの Python では、型の階層構造にこのような追加がなされるかもしれません。

以下に説明する型のいくつかには、’特殊属性 (special attribute)’ と題された段落が連ねられています。これらの属性は実装へのアクセス手段を提供するもので、一般的な用途に利用するためのものではありません。特殊属性の定義は将来変更される可能性があります。

None

この型には単一の値しかありません。この値を持つオブジェクトはただ一つしか存在しません。このオブジェクトは組み込み名 None でアクセスされます。このオブジェクトは、様々な状況で値が存在しないことをしめします。例えば、明示的に値を返さない関数は None を返します。 None の真値 (truth value) は 偽 (false) です。

NotImplemented

この型には単一の値しかありません。この値を持つオブジェクトはただ一つしか存在しません。このオブジェクトは組み込み名 NotImplemented でアクセスされます。数値演算に関するメソッドや拡張比較 (rich comparison) メソッドは、被演算子が該当する演算を行うための実装をもたない場合、この値を返すことがあります。(演算子によっては、インタプリタが関連のある演算を試したり、他の代替操作を行います。) 真値は真 (true) です。

Ellipsis

この型には単一の値しかありません。この値を持つオブジェクトはただ一つしか存在しません。このオブジェクトはリテラル ... または組み込み名 Ellipsis でアクセスされます。真理値は真 (true)です。

numbers.Number

数値リテラルによって作成されたり、算術演算や組み込みの算術関数によって返されるオブジェクトです。数値オブジェクトは変更不能です; 一度値が生成されると、二度と変更されることはありません。Python の数値オブジェクトはいうまでもなく数学で言うところの数値と強く関係していますが、コンピュータ内で数値を表現する際に伴う制限を受けています。

Python は整数、浮動小数点数、複素数の間で区別を行っています:

numbers.Integral

整数型は、整数(正の数および負の数)を表す数学的集合内における要素を表現する型です。

整数には 2 種類あります:

整数 (int)

整数は無限の定義域を持ち、利用可能な (仮想) メモリサイズの制限のみをうけます。整数はシフト演算やマスク演算のためにバイナリ表現をもつものと仮定されます。負の数は符号ビットが左に無限に延びているような錯覚を与える 2 の補数表現の変型で表されます。

ブール値 (bool)

真偽値の False と True を表します。 FalseTrue を表す 2 つのオブジェクトのみがブール値オブジェクトです。 ブール型は整数型の部分型であり、ほとんどの状況でそれぞれ 0 と 1 のように振る舞いますが、例外として文字列に変換されたときはそれぞれ "False" および "True" という文字列が返されます。

整数表現に関する規則は、負の整数を含むシフト演算やマスク演算において、最も有意義な解釈ができるように意図されています。

numbers.Real (float)

この型は計算機レベルで倍精度とされている浮動小数点数を表現します。表現可能な値の範囲やオーバフローの扱いは、根底にある計算機アーキテクチャ (と C または Java 実装) 次第です。 Python は単精度の浮動小数点数をサポートしません; 単精度の数を使う理由は、通常プロセッサやメモリ使用量の節約ですが、こうした節約は Python でオブジェクトを扱う際のオーバヘッドに比べれば微々たるものにすぎません。従って、わざわざ浮動小数点型を 2 つも定義してPython 言語を難解にする理由はどこにもないのです。

numbers.Complex (complex)

この型は、計算機レベルで倍精度とされている浮動小数点を 2 つ一組にして複素数を表現します。浮動小数点について述べたのと同じ性質が当てはまります。複素数 z の実数部および虚数部は、それぞれ読み出し専用属性 z.real および z.imag で取り出すことができます。

シーケンス

この型は、有限の順序集合 (ordered set) を表現します。要素は非負の整数でインデックス化されています。組み込み関数 len() を使うと、シーケンスの要素数を返します。シーケンスの長さが n の場合、インデックスは 0, 1, ..., n -1 からなる集合です。シーケンス a の要素 ia[i] で選択します。

シーケンスはスライス操作 (slice) もサポートしています: a[i:j] とすると、 i <= k < j であるインデックス k をもつ全ての要素を選択します。式表現としてスライスを用いた場合、スライスは同じ型をもつ新たなシーケンスを表します。新たなシーケンス内では、インデックス集合が 0 から始まるようにインデックスの値を振りなおします。

シーケンスによっては、第三の “ステップ (step)” パラメータを持つ “拡張スライス (extended slice)” もサポートしています: a[i:j:k] は、 x = i + n*k, n >= 0 かつ i <= x < j であるようなインデックス x を持つような a 全ての要素を選択します。

シーケンスは、変更可能なものか、そうでないかで区別されています:

変更不能なシーケンス

変更不能なシーケンス型のオブジェクトは、一度生成されるとその値を変更することができません。 (オブジェクトに他のオブジェクトへの参照が入っている場合、参照されているオブジェクトは変更可能なオブジェクトでもよく、その値は変更される可能性があります; しかし、変更不能なオブジェクトが直接参照しているオブジェクトの集合自体は、変更することができません。)

以下の型は変更不能なシーケンス型です:

文字列

文字列は、Unicode コードポイントを表す値のシーケンスです。範囲 U+0000 - U+10FFFF 内の全てのコードポイントが文字列で表せます。Python には chr 型が無く、文字列内の全ての文字は長さ 1 の文字列として表されます。組み込み関数 ord() は、文字をそのコードポイントに (整数として) 変換します。 chr() は、範囲 0 - 10FFFF 内の整数を対応する文字に変換します。 str.encode() を使って、 str を与えられたエンコーディングで bytes に変換できます。 bytes.decode() で、その逆ができます。

タプル

タプルの要素は任意の Python オブジェクトです。二つ以上の要素からなるタプルは、個々の要素を表現する式をカンマで区切って構成します。単一の要素からなるタプル (単集合 ‘singleton’) を作るには、要素を表現する式の直後にカンマをつけます (単一の式だけではタプルを形成しません。これは、式をグループ化するのに丸括弧を使えるようにしなければならないからです) 。要素の全くない丸括弧の対を作ると空のタプルになります。

bytes

bytes オブジェクトは不変な配列です。 要素は 8-bit バイトで、 0 <= x < 256 の範囲の整数で表現されます。 (b'abc' のような) bytes リテラルや組み込み関数の bytes() を使って bytes オブジェクトを作成できます。 また、 bytes オブジェクトは decode() メソッドを通して文字列にデコードできます。

変更可能なシーケンス

変更可能なシーケンスは、作成した後で変更することができます。変更可能なシーケンスでは、添字表記やスライス表記を使って指定された要素に代入を行うことができ、 del (delete) 文を使って要素を削除することができます。

Python に最初から組み込まれている変更可能なシーケンス型は、今のところ二つです:

リスト

リストの要素は任意の Python オブジェクトにできます。リストは、角括弧の中にカンマで区切られた式を並べて作ります。 (長さが 0 や 1 のシーケンスを作るために特殊な場合分けは必要ないことに注意してください。)

バイト配列

bytearray オブジェクトは変更可能な配列です。組み込みの bytearray() コンストラクタによって作成されます。変更可能なことを除けば (つまりハッシュ化できない)、 byte array は変更不能な bytes オブジェクトと同じインターフェースと機能を提供します。

拡張モジュール array や、 collections モジュールには、さらなるミュータブルなシーケンス型の例があります。

集合型

集合型は、順序のない、ユニークで不変なオブジェクトの有限集合を表現します。そのため、(配列の)添字を使ったインデックスアクセスはできません。ただし、イテレートは可能で、組み込み関数 len() は集合の要素数を返します。集合型の一般的な使い方は、集合に属しているかの高速なテスト、シーケンスからの重複の排除、共通集合・和集合・差・対称差といった数学的な演算の計算です。

集合の要素には、辞書のキーと同じ普遍性に関するルールが適用されます。数値型は通常の数値比較のルールに従うことに注意してください。もし2つの数値の比較結果が同値である(例えば、 11.0)なら、そのうちの1つのみを集合に含めることができます。

現在、2つの組み込み集合型があります:

集合型

可変な集合型です。 組み込みの set() コンストラクタで作成され、後から add() などのいくつかのメソッドで更新できます。

Frozen set 型

不変な集合型です。組み込みの frozenset() コンストラクタによって作成されます。 frozenset は不変でハッシュ可能(hashable)なので、別の集合型の要素になったり、辞書のキーにすることができます。

マップ型

任意のインデックス集合でインデックス化された、有限のオブジェクトからなる集合を表現します。添字表記 a[k] は、 k でインインデックス指定された要素を a から選択します; 選択された要素は式の中で使うことができ、代入や del 文の対象にすることができます。組み込み関数 len() は、マップ内の要素数を返します。

Python に最初から組み込まれているマップ型は、今のところ一つだけです:

辞書

ほとんどどんな値でもインデックスとして使えるような、有限個のオブジェクトからなる集合を表します。キー値 (key) として使えない値は、リストや辞書を含む値や、同一性ではなく値でオブジェクトが比較される、その他の変更可能な型です。これは、辞書型を効率的に実装する上で、キーのハッシュ値が一定であることが必要だからです。数値型をキーに使う場合、キー値は通常の数値比較における規則に従います: 二つの値が等しくなる場合 (例えば 11.0)、互いに同じ辞書のエントリを表すインデックスとして使うことができます。

辞書は変更可能な型です; 辞書は {...} 表記で生成します (辞書表現 を参照してください)。

拡張モジュール dbm.ndbmdbm.gdbm は、 collections モジュールのように、別のマッピング型の例を提供しています。

呼び出し可能型

関数呼び出し操作 (呼び出し (call) 参照) を行うことができる型です:

ユーザ定義関数

ユーザ定義関数オブジェクトは、関数定義を行うことで生成されます (関数定義 参照)。関数は、仮引数 (formal parameter) リストと同じ数の要素が入った引数リストとともに呼び出されます。

特殊属性:

属性

意味

 
__doc__

関数のドキュメンテーション文字列です。ドキュメンテーションがない場合は None になります。

書き込み可能

__name__

関数の名前です。

書き込み可能

__qualname__

関数の qualified name です。

バージョン 3.3 で追加.

書き込み可能

__module__

関数が定義されているモジュールの名前です。モジュール名がない場合は None になります。

書き込み可能

__defaults__

デフォルト値を持つ引数に対するデフォルト値が収められたタプルで、デフォルト値を持つ引数がない場合には None になります。

書き込み可能

__code__

コンパイルされた関数本体を表現するコードオブジェクトです。

書き込み可能

__globals__

関数のグローバル変数の入った辞書 (への参照) です — この辞書は、関数が定義されているモジュールのグローバルな名前空間を決定します。

読み込み専用

__dict__

任意の関数属性をサポートするための名前空間が収められています。

書き込み可能

__closure__

None または関数の個々の自由変数 (引数以外の変数) に対して値を結び付けているセル (cell) 群からなるタプルになります。

読み込み専用

__annotations__

パラメータの注釈が入った辞書です。 辞書のキーはパラメータ名で、返り値の注釈がある場合は、 'return' がそのキーとなります。

書き込み可能

__kwdefaults__

キーワード専用パラメータのデフォルト値を含む辞書です。

書き込み可能

「書き込み可能」とラベルされている属性のほとんどは、代入された値の型をチェックします。

関数オブジェクトはまた、任意の属性を設定したり取得したりできます。この機能は、例えば関数にメタデータを付与したい場合などに使えます。関数の get や set には、通常のドット表記を使います。 現在の実装では、ユーザ定義の関数でのみ属性をサポートしているので注意して下さい。組み込み関数の属性は将来サポートする予定です。

関数定義に関するその他の情報は、関数のコードオブジェクトから得られます; 後述の内部型 (internal type) に関する説明を参照してください。

インスタンスメソッド

インスタンスメソッドオブジェクトは、クラス、クラスインスタンスと任意の呼び出し可能オブジェクト (通常はユーザ定義関数) を結びつけます。

読み出し専用の特殊属性: __self__ はクラスインスタンスオブジェクトで、 __func__ は関数オブジェクトです; __doc__ はメソッドのドキュメンテーション文字列 (__func__.__doc__ と同じ) です; __name__ はメソッドの名前 (__func__.__name__ と同じ) です; __module__ はメソッドが定義されたモジュールの名前か、モジュール名がない場合は None になります。

メソッドもまた、根底にある関数オブジェクトの任意の関数属性に (値の設定はできませんが) アクセスできます。

クラスの属性を (場合によってはそのクラスのインスタンスを介して) 取得するとき、その属性がユーザ定義の関数オブジェクトまたはクラスメソッドオブジェクトであれば、ユーザ定義メソッドオブジェクトが生成されることがあります。

クラスからインスタンスを経由してユーザ定義関数オブジェクトを取得することによってインスタンスメソッドオブジェクトが生成されたとき、 __self__ 属性はそのインスタンスで、このメソッドオブジェクトは束縛されている (bound) といいます。新しいメソッドの __func__ 属性はもとの関数オブジェクトです。

クラスやインスタンスから他のメソッドオブジェクトを取得することによってユーザ定義メソッドオブジェクトが生成されたとき、その動作は関数オブジェクトの場合と同様ですが、新しいインスタンスの __func__ 属性はもとのメソッドオブジェクトではなく、その __func__ 属性です。

クラスやインスタンスからクラスメソッドオブジェクトを取得することによってインスタンスメソッドオブジェクトが生成されたとき、 __self__ 属性はクラスそのもので、 __func__ 属性はクラスメソッドの根底にある関数オブジェクトです。

インスタンスメソッドオブジェクトが呼び出される際、根底にある関数 (__func__) が呼び出されます。このとき、クラスインスタンス (__self__) が引数リストの先頭に挿入されます。例えば、 C を関数 f() の定義を含むクラス、 xC のインスタンスとすると、 x.f(1) の呼び出しは C.f(x, 1) の呼び出しと同じです。

クラスメソッドオブジェクトからインスタンスメソッドオブジェクトが導出される際、 __self__ に記憶されている “クラスインスタンス” は実際はクラスそのものなので、 x.f(1)C.f(1) の呼び出しは、根底にある関数を f として f(C,1) の呼び出しと等価です。

なお、関数オブジェクトからインスタンスメソッドオブジェクトへの変換は、インスタンスから属性が取り出されるたびに行われます。場合によっては、属性をローカル変数に代入しておき、そのローカル変数を呼び出すようにするのが効果的な最適化になります。また、上記の変換はユーザ定義関数に対してのみ行われます; その他の呼び出し可能オブジェクト (および呼び出し可能でない全てのオブジェクト) は、変換されずに取り出されます。それから、クラスインスタンスの属性になっているユーザ定義関数は、束縛メソッドに変換されません; 変換されるのは、関数がクラスの属性である場合 だけ です。

ジェネレータ関数

yield 文 (yield 文 の節を参照) を使う関数もしくはメソッドは ジェネレータ関数 と呼ばれます。 そのような関数が呼び出されたときは常に、関数の本体を実行するのに使えるイテレータオブジェクトを返します: イテレータの iterator.__next__() メソッドを呼び出すと、 yield 文を使って値が提供されるまで関数を実行します。 関数の return 文を実行するか終端に達したときは、 StopIteration 例外が送出され、イテレータが返すべき値の最後まで到達しています。

組み込み関数

組み込み関数オブジェクトはC関数へのラッパーです。組み込み関数の例は len()math.sin() (math は標準の組み込みモジュール) です。引数の数や型は C 関数で決定されています。読み出し専用の特殊属性: __doc__ は関数のドキュメンテーション文字列です。ドキュメンテーションがない場合は None になります; __name__ は関数の名前です; __self__None に設定されています (組み込みメソッドの節も参照してください); __module__ は、関数が定義されているモジュールの名前です。モジュール名がない場合は None になります。

組み込みメソッド

実際には組み込み関数を別の形で隠蔽したもので、こちらの場合には C 関数に渡される何らかのオブジェクトを非明示的な外部引数として持っています。組み込みメソッドの例は、 alist をリストオブジェクトとしたときの alist.append() です。この場合には、読み出し専用の属性 __self__alist で表されるオブジェクトになります。

クラス

クラスは呼び出し可能です。そのオブジェクトは通常、そのクラスの新たなインスタンスのファクトリとして振舞いますが、 __new__() をオーバーライドして、バリエーションを持たせることもできます。呼び出しに使われた引数は、 __new__() と、典型的な場合では __init__() に渡され、新たなインスタンスの初期化に使われます。

クラスのインスタンス

任意のクラスのインスタンスは、クラスで __call__() メソッドを定義することで呼び出し可能になります。

モジュール

モジュールは Python コードの基礎的な組織単位で、 import 文あるいは importlib.import_module() や組み込みの __import__() のような関数を呼び出すことで起動される import system によって作成されます (import を参照)。モジュールオブジェクトは、辞書オブジェクト (これは、モジュール内で定義された関数の __globals__ 属性から参照される辞書です) で実装された名前空間を持っています。属性の参照は、この辞書の検索に翻訳されます。例えば、 m.xm.__dict__["x"] と等価です。モジュールオブジェクトは、モジュールの初期化に使われるコードオブジェクトを含んでいません (初期化が終わればもう必要ないからです)。

属性の代入を行うと、モジュールの名前空間辞書の内容を更新します。例えば、 m.x = 1m.__dict__["x"] = 1 と同じです。

読み出し専用の特殊属性: __dict__ はモジュールの名前空間で、辞書オブジェクトです。

CPython がモジュール辞書を削除する方法により、モジュール辞書が生きた参照を持っていたとしてもその辞書はモジュールがスコープから外れた時に削除されます。これを避けるには、辞書をコピーするか、辞書を直接使っている間モジュールを保持してください。

定義済みの (書き込み可能な) 属性: __name__ はモジュールの名前です; __doc__ は関数のドキュメンテーション文字列です。ドキュメンテーションがない場合は None になります; モジュールがファイルからロードされた場合、 __file__ はロードされたモジュールファイルのパス名です。インタプリタに静的にリンクされている C モジュールのような特定の種類のモジュールでは、 __file__ 属性は存在しないかもしれません; 共有ライブラリから動的にロードされた拡張モジュールの場合、この属性は 共有ライブラリファイルのパス名になります。

カスタムクラス型

カスタムクラス型は通常、クラス定義 (クラス定義 参照) で生成されます。クラスは辞書オブジェクトで実装された名前空間を持っています。クラス属性の参照は、この辞書に対する探索 (lookup) に翻訳されます。例えば、 C.xC.__dict__["x"] に翻訳されます (ただし、属性参照の意味を変えられる幾つかのフックがあります)。属性がこの探索で見つからないとき、その基底クラスで探索が続けられます。基底クラスのこの探索は、C3 メソッド解決順序 (MRO=method resolution order) を利用していて、複数の継承経路が共通の祖先につながる「ダイアモンド」継承構造があっても正しく動作します。 C3 MRO についてのより詳細な情報は、 2.3リリースに付属するドキュメント http://www.python.org/download/releases/2.3/mro/ にあります。

クラス (C とします) 属性参照で、クラスメソッドオブジェクト得ようとするとき、 __self__ 属性が C であるようなインスタンスメソッドオブジェクトに変換されます。静的メソッドオブジェクトを得ようとするとき、静的メソッドオブジェクトでラップされたオブジェクトに変換されます。クラスから取り出した属性と実際に __dict__ に入っているものが異なるような他の方法は、 デスクリプタ (descriptor) の実装 を参照してください。

クラス属性を代入すると、そのクラスの辞書だけが更新され、基底クラスの辞書は更新しません。

クラスオブジェクトを呼び出す (上記を参照) と、クラスインスタンスを生成します (下記を参照)。

特殊属性: __name__ はクラス名です; __module__ はクラスが定義されたモジュール名です; __dict__ はクラスが持つ名前空間が入った辞書です; __bases__ は基底クラスからなるタプル (空もしくは要素が 1 つしかないこともあります) で、基底クラスのリストに表れる順序で並んでいます; __doc__ はクラスのドキュメント文字列で、未定義の場合は None です。

クラスインスタンス

クラスインスタンスは、クラスオブジェクト (上記参照) を呼び出すことで生成されます。クラスインスタンスは辞書で実装された名前空間を持っており、属性参照の時にはまずこの辞書が探索されます。ここで属性が見つからず、インスタンスのクラスにその名前の属性があるとき、検索はクラス属性にまで広げられます。見つかったクラス属性がユーザ定義関数オブジェクトであったなら、それは __self__ 属性がそのインスタンスであるようなインスタンスメソッドオブジェクトに変換されます。静的メソッドやクラスメソッドオブジェクトも同様に変換されます; 上記の “クラス” を参照してください。インスタンスを通してクラスから取り出した属性と、実際に __dict__ に保存されているものが異なる可能性のある他の状況は デスクリプタ (descriptor) の実装 節を参照してください。クラス属性が見つからず、かつオブジェクトのクラスが __getattr__() メソッドを持っているなら、探索要求を満たすためにこのメソッドが呼び出されます。

属性の代入や削除を行うと、インスタンスの辞書を更新しますが、クラスの辞書を更新することはありません。クラスで __setattr__()__delattr__() メソッドが定義されている場合、直接インスタンスの辞書を更新する代わりにこれらのメソッドが呼び出されます。

クラスインスタンスは、ある特定の名前のメソッドを持っている場合、数値型やシーケンス型、あるいはマップ型のように振舞うことができます。 特殊メソッド名 を参照してください。

特殊属性: __dict__ は属性の辞書です; __class__ はインスタンスのクラスです。

I/O オブジェクト (ファイルオブジェクトの別名)

file object は開かれたファイルを表します。 ファイルオブジェクトを作るための様々なショートカットがあります: open() 組み込み関数、 os.popen()os.fdopen() 、ソケットオブジェクトの makefile() メソッド (あるいは拡張モジュールから提供される他の関数やメソッド) 。

オブジェクト sys.stdinsys.stdout および sys.stderr は、インタプリタの標準入力、標準出力、および標準エラー出力ストリームに対応するファイルオブジェクトに初期化されます。これらはすべてテキストモードで開かれ、 io.TextIOBase 抽象クラスによって定義されたインタフェースに従います。

内部型

インタプリタが内部的に使っているいくつかの型は、ユーザに公開されています。これらの定義は将来のインタプリタのバージョンでは変更される可能性がありますが、ここでは記述の完全性のために触れておきます。

コードオブジェクト

コードオブジェクトは バイトコンパイルされた (byte-compiled) 実行可能な Python コード、別名バイトコード(bytecode) を表現します。コードオブジェクトと関数オブジェクトの違いは、関数オブジェクトが関数のグローバル変数 (関数を定義しているモジュールのグローバル) に対して明示的な参照を持っているのに対し、コードオブジェクトにはコンテキストがないということです; また、関数オブジェクトではデフォルト引数値を記憶できますが、コードオブジェクトではできません (実行時に計算される値を表現するため)。関数オブジェクトと違い、コードオブジェクトは変更不可能で、変更可能なオブジェクトへの参照を (直接、間接に関わらず) 含みません。

読み出し専用の特殊属性: co_name は関数名を表します; co_argcount は固定引数 (positional argument) の数です; co_nlocals は関数が使う (引数を含めた) ローカル変数の数です; co_varnames はローカル変数名の入ったタプルです (引数名から始まっています); co_cellvars はネストされた関数で参照されているローカル変数の名前が入ったタプルです; co_freevars は自由変数の名前が入ったタプルです。 co_code はバイトコード列を表現している文字列です; co_consts はバイトコードで使われているリテラルの入ったタプルです; co_names はバイトコードで使われている名前の入ったタプルです; co_filename はバイトコードのコンパイルが行われたファイル名です; co_firstlineno は関数の最初の行番号です; co_lnotab はバイトコードオフセットから行番号への対応付けをコード化した文字列です (詳細についてはインタプリタのソースコードを参照してください); co_stacksize は関数で (ローカル変数の分も含めて) 必要なスタックサイズです; co_flags はインタプリタ用の様々なフラグをコード化した整数です。

以下のフラグビットが co_flags で定義されています: 0x04 ビットは、関数が *arguments 構文を使って任意の数の固定引数を受理できる場合に立てられます; 0x08 ビットは、関数が **keywords 構文を使ってキーワード引数を受理できる場合に立てられます; 0x20 ビットは、関数がジェネレータである場合に立てられます。

将来機能 (future feature) 宣言 (from __future__ import division) もまた、 co_flags のビットを立てることで、コードオブジェクトが特定の機能を有効にしてコンパイルされていることを示します: 0x2000 ビットは、関数が将来機能を有効にしてコンパイルされている場合に立てられます; 以前のバージョンの Python では、 0x10 および 0x1000 ビットが使われていました。

co_flags のその他のビットは将来に内部的に利用するために予約されています。

コードオブジェクトが関数を表現している場合、 co_consts の最初の要素は関数のドキュメンテーション文字列になります。ドキュメンテーション文字列が定義されていない場合には None になります。

フレームオブジェクト

フレームオブジェクトは実行フレーム (execution frame) を表します。実行フレームはトレースバックオブジェクト内に出現します (下記参照)。

読み出し専用の特殊属性: f_back は直前のスタックフレーム (呼び出し側の方向) で、それがスタックフレームの最下段なら None です; f_code はそのフレームで実行されているコードオブジェクトです; f_locals はローカル変数の探索に使われる辞書です; f_globals はグローバル変数に使われます; f_builtins は組み込みの (Python 固有の) 名前に使われます; f_lasti は厳密な命令コード (コードオブジェクトのバイトコード文字列へのインデックス) です。

書き込み可能な特殊属性: f_trace は、 None でなければ、ソースコードの各行の先頭で呼び出される関数です (デバッガに使われます); f_lineno はフレーム中における現在の行番号です — トレース関数 (trace function) 側でこの値に書き込みを行うと、指定した行にジャンプします (最下段の実行フレームにいるときのみ)。デバッガでは、 f_fileno を書き込むことで、ジャンプ命令 (Set Next Statement 命令とも) を実装できます。

トレースバックオブジェクト

トレースバックオブジェクトは例外のスタックトレースを表します。トレースバックオブジェクトは例外が発生した際に生成されます。例外ハンドラの検索が実行スタックを戻っていく際、戻ったレベル毎に、トレースバックオブジェクトが現在のトレースバックの前に挿入されます。例外ハンドラに入ると、スタックトレースをプログラム側で利用できるようになります。 (try 文 を参照。) トレースバックは、 sys.exc_info() が返すタプルの三番目の要素として得られます。プログラムに適切なハンドラがないとき、スタックトレースは (うまく書式化されて) 標準エラーストリームに書き出されます; インタプリタが対話的に実行されている場合、 sys.last_traceback として得ることもできます。

読み出し専用の特殊属性: tb_next はスタックトレース内の (例外の発生しているフレームに向かって) 次のレベルです。次のレベルが存在しない場合には None になります; tb_frame は現在のレベルにおける実行フレームを指します; tb_lineno は例外の発生した行番号です; tb_lasti は厳密な命令コードです。トレースバック内の行番号や最後に実行された命令は、 try 文内で例外が発生し、かつ対応する except 節や finally 節がない場合には、フレームオブジェクト内の行番号とは異なるかもしれません。

スライスオブジェクト

スライスオブジェクトは、 __getitem__() メソッドのためのスライスを表すのに使われます。スライスオブジェクトは組み込みの slice() 関数でも生成されます。

読み込み専用の特殊属性: start は下限です; stop は上限です; step はステップの値です; それぞれ省略された場合は None となっています。 これらの属性は任意の型を持てます。

スライスオブジェクトはメソッドを一つサポートします:

slice.indices(self, length)

このメソッドは単一の整数引数 length を取り、スライスオブジェクトが length 要素のシーケンスに適用されたときに表現する、スライスに関する情報を計算します。このメソッドは 3 つの整数からなるタプルを返します; それぞれ start および stop のインデックスと、 step すなわちスライスのまたぎ幅です。インデックス値がないか、範囲外の値であれば、通常のスライスと変わらないやりかたで扱われます。

静的メソッドオブジェクト

静的メソッドは、上で説明したような関数オブジェクトからメソッドオブジェクトへの変換を阻止するための方法を提供します。静的メソッドオブジェクトは他の何らかのオブジェクト、通常はユーザ定義メソッドオブジェクトを包むラッパーです。静的メソッドをクラスやクラスインスタンスから取得すると、実際に返されるオブジェクトはラップされたオブジェクトになり、それ以上は変換の対象にはなりません。静的メソッドオブジェクトは通常呼び出し可能なオブジェクトをラップしますが、静的オブジェクト自体は呼び出すことができません。静的オブジェクトは組み込みコンストラクタ staticmethod() で生成されます。

クラスメソッドオブジェクト

クラスメソッドオブジェクトは、静的メソッドオブジェクトに似て、別のオブジェクトを包むラッパーであり、そのオブジェクトをクラスやクラスインスタンスから取り出す方法を代替します。このようにして取得したクラスメソッドオブジェクトの動作については、上の “ユーザ定義メソッド (user-defined method)” で説明されています。クラスメソッドオブジェクトは組み込みのコンストラクタ classmethod() で生成されます。

3.3. 特殊メソッド名

クラスは、特殊な名前のメソッドを定義して、特殊な構文 (算術演算や添え字表記、スライス表記など) による特定の演算を実装できます。これは、Python の演算子オーバロード (operator overloading) へのアプローチです。これにより、クラスは言語の演算子に対する独自の振る舞いを定義できます。例えば、あるクラスが __getitem__() という名前のメソッドを定義しており、 x がこのクラスのインスタンスであるとすると、 x[i]type(x).__getitem__(x, i) とほぼ等価です。特に注釈のない限り、適切なメソッドが定義されていないとき、このような演算を試みると例外 (たいていは AttributeErrorTypeError) が送出されます。

組み込み型を模倣するクラスを実装するときは、真似されるオブジェクトにとって意味がある範囲に実装をとどめるのが重要です。 例えば、あるシーケンスは個々の要素の取得はきちんと動くかもしれませんが、スライスの展開が意味を為さないかもしれません。 (W3C のドキュメントオブジェクトモデルにある NodeList インターフェースがその一例です。)

3.3.1. 基本的なカスタマイズ

object.__new__(cls[, ...])

クラス cls の新しいインスタンスを作るために呼び出されます。 __new__() は静的メソッドで (このメソッドは特別扱いされているので、明示的に静的メソッドと宣言する必要はありません)、インスタンスを生成するよう要求されているクラスを第一引数にとります。残りの引数はオブジェクトのコンストラクタの式 (クラスの呼び出し文) に渡されます。 __new__() の戻り値は新しいオブジェクトのインスタンス (通常は cls のインスタンス) でなければなりません。

典型的な実装では、クラスの新たなインスタンスを生成するときには super(currentclass, cls).__new__(cls[, ...]) に適切な引数を指定してスーパクラスの __new__() メソッドを呼び出し、新たに生成されたインスタンスに必要な変更を加えてから返します。

__new__()cls のインスタンスを返した場合、 __init__(self[, ...]) のようにしてインスタンスの __init__() が呼び出されます。このとき、 self は新たに生成されたインスタンスで、残りの引数は __new__() に渡された引数と同じになります。

__new__()cls のインスタンスを返さない場合、インスタンスの __init__() メソッドは呼び出されません。

__new__() の主な目的は、変更不能な型 (int, str, tuple など) のサブクラスでインスタンス生成をカスタマイズすることにあります。また、クラス生成をカスタマイズするために、カスタムのメタクラスでよくオーバーライドされます。

object.__init__(self[, ...])

Called after the instance has been created (by __new__()), but before it is returned to the caller. The arguments are those passed to the class constructor expression. If a base class has an __init__() method, the derived class’s __init__() method, if any, must explicitly call it to ensure proper initialization of the base class part of the instance; for example: BaseClass.__init__(self, [args...]).

Because __new__() and __init__() work together in constructing objects (__new__() to create it, and __init__() to customise it), no non-None value may be returned by __init__(); doing so will cause a TypeError to be raised at runtime.

object.__del__(self)

インスタンスが消滅させられる際に呼び出されます。このメソッドはデストラクタ (destructor) とも呼ばれます。基底クラスが __del__() メソッドを持っている場合、派生クラスの __del__() メソッドでは、必要ならば明示的に基底クラスの __del__() メソッドを呼び出して、インスタンスの基底クラスに関わる部分が正しく消滅処理されるようにしなければなりません。 __del__() メソッドでインスタンスに対する新たな参照を作ることで、インスタンスの消滅を遅らせることができます (とはいえ、推奨しません!)。このようにすると、新たに作成された参照がその後削除された際にもう一度 __del__() メソッドが呼び出されます。インタプリタが終了する際に残っているオブジェクトに対して、 __del__() メソッドが呼び出される保証はありません。

注釈

del xx.__del__() を直接呼び出すことはしません — 前者は x への参照カウント (reference count) を 1 つ減らし、後者は x への参照カウントが 0 になった際にのみ呼び出されます。よくオブジェクトの参照カウントが 0 になるのを妨げる要因となる状況には、以下のようなものがあります: 複数のオブジェクト間における循環参照 (二重リンクリストや、親と子へのポインタを持つツリーデータ構造); 例外を捕捉した関数におけるスタックフレーム上にあるオブジェクトへの参照 (sys.exc_info()[2] に記憶されているトレースバックが、スタックフレームを生き延びさせます); または、対話モードでハンドルされなかった例外を送出したスタックフレーム上のオブジェクトへの参照 (sys.last_traceback に記憶されているトレースバックが、スタックフレームを生き延びさせます); 最初の状況を解決するには、明示的に循環参照を壊すしかありません; 後者の二つの状況は、 sys.exc_tracebacksys.last_tracebackNone を格納することで解決できます。ごみオブジェクトと化したオプションの循環参照検出機構 (cycle detector) が有効 (これはデフォルトの設定です) にされていれば循環参照は検出されますが、検出された循環参照を消去するのは Python レベルで __del__() メソッドが定義されていないときだけです。 __del__() メソッドが循環参照検出機構でどのように扱われるか、とりわけ garbage 値の記述に関しては、 gc モジュールのドキュメントを参照してください。

警告

__del__() メソッドの呼び出しが起きるのは不安定な状況下なので、 __del__() の実行中に発生した例外は無視され、代わりに sys.stderr に警告が出力されます。また、 (例えばプログラムの実行終了による) モジュールの削除に伴って __del__() が呼び出される際には、 __del__() メソッドが参照している他のグローバル変数はすでに削除されていたり、削除中(例えば、import機構のシャットダウン中)かもしれません。この理由から、 __del__() メソッドでは外部の不変関係を維持する上で絶対最低限必要なことだけをすべきです。バージョン 1.5 からは、単一のアンダースコアで始まるようなグローバル変数は、他のグローバル変数が削除される前にモジュールから削除されるように Python 側で保証しています; これらのアンダースコア付きグローバル変数は、 __del__() が呼び出された際に、import されたモジュールがまだ残っているか確認する上で役に立ちます。

object.__repr__(self)

repr() 組み込み関数によって呼び出され、オブジェクトを表す「公式の (official)」文字列を計算します。可能なら、これは (適切な環境が与えられれば) 同じ値のオブジェクトを再生成するのに使える、有効な Python 式のようなものであるべきです。できないなら、 <...some useful description...> 形式の文字列が返されるべきです。戻り値は文字列オブジェクトでなければなりません。クラスが __repr__() を定義していて __str__() は定義していなければ、そのクラスのインスタンスの「非公式の (informal)」文字列表現が要求されたときにも __repr__() が使われます。

この関数はデバッグの際によく用いられるので、たくさんの情報を含み、あいまいでないような表記にすることが重要です。

object.__str__(self)

オブジェクトの「非公式の (informal)」あるいは表示に適した文字列表現を計算するために、 str(object) と組み込み関数 format(), print() によって呼ばれます。戻り値は string オブジェクトでなければなりません。

__str__() が有効な Python 表現を返すことが期待されないという点で、このメソッドは object.__repr__() とは異なります: より便利な、または簡潔な表現を使用することができます。

組み込み型 object によって定義されたデフォルト実装は、 object.__repr__() を呼び出します。

object.__bytes__(self)

bytes() によって呼び出され、オブジェクトのバイト文字列表現を計算します。これは bytes オブジェクトを返すべきです。

object.__format__(self, format_spec)

format() 組み込み関数 (さらにその延長でクラス strstr.format() メソッド) によって呼び出され、オブジェクトの “フォーマット化された (formatted)” 文字列表現を作ります。 format_spec 引数は、 必要なフォーマット化オプションの記述を含む文字列です。 format_spec 引数の解釈は、 __format__() を実装する型によりますが、 ほとんどのクラスは組み込み型のいずれかにフォーマット化を委譲したり、 同じようなフォーマット化オプション構文を使います。

標準のフォーマット構文の解説は、 書式指定ミニ言語仕様 (Format Specification Mini-Language) を参照してください。

戻り値は文字列オブジェクトでなければなりません。

object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)

これらはいわゆる “拡張比較 (rich comparison)” メソッドです。演算子シンボルとメソッド名の対応は以下の通りです: x<yx.__lt__(y) を呼び出します; x<=yx.__le__(y) を呼び出します; x==yx.__eq__(y) を呼び出します; x!=yx.__ne__(y) を呼び出します; x>yx.__gt__(y) を呼び出します; x>=yx.__ge__(y) を呼び出します。

拡張比較メソッドは、与えられた引数のペアに対する操作を実装していないときに、 NotImplemented というシングルトンを返すかもしれません。慣例として、正常に比較が行われたときには FalseTrue を返します。しかし、これらのメソッドは任意の値を返すことができるので、比較演算子がブール値のコンテキスト(たとえば、 if 文の条件部分)で使われた場合、 Python はその値に対して bool() を呼び出して結果の真偽を判断します。

比較演算子間には、暗黙的な論理関係はありません。すなわち、 x==y が真である場合、暗黙のうちに x!=y が偽になるわけではありません。従って、 __eq__() を実装する際、演算子が期待通りに動作するようにするために __ne__() も定義する必要があります。カスタムの比較演算をサポートしていて、辞書のキーに使うことができるハッシュ可能(hashable) オブジェクトを作るときの重要な注意点について、 __hash__() のドキュメント内に書かれているので参照してください。

これらのメソッドには、(左引数が演算をサポートしないが、右引数はサポートする場合に用いられるような) 鏡像となる (引数を入れ替えた) バージョンは存在しません; むしろ、 __lt__()__gt__() は互いに鏡像であり、 __le__()__ge__() 、および __eq__()__ne__() はそれぞれ互いに鏡像です。

拡張比較メソッドの引数には型強制 (coerce) が起こりません。

単一の基本演算から順序付けするための演算を自動的に生成したい場合には、 functools.total_ordering() を参照してください。

object.__hash__(self)

組み込みの hash() 関数や、 set, frozenset, dict のようなハッシュを使ったコレクション型の要素に対する操作から呼び出されます。 __hash__() は整数を返さなければなりません。このメソッドに必要な性質は、比較結果が等しいオブジェクトは同じハッシュ値を持つということです。オブジェクトを比較するときに利用する要素のそれぞれのハッシュ値を、(排他的論理和等の) なんらかの方法で合成することをおすすめします。

注釈

hash() はオブジェクト独自の __hash__() メソッドから返された値を Py_ssize_t のサイズに切り詰めます。 これは 64-bit でビルドされていると 8 バイトで、 32-bit でビルドされていると 4 バイトです。 オブジェクトの __hash__() が異なる bit サイズのビルドでも可搬性が無ければならない場合は、必ず全てのサポートするビルドの bit 幅をチェックしてください。 それをする簡単な方法は python -c "import sys; print(sys.hash_info.width)" を実行することです。

クラスが __eq__() メソッドを定義していないなら、 __hash__() メソッドも定義してはなりません; クラスが __eq__() を定義していても __hash__() を定義していないなら、そのインスタンスはハッシュ可能コレクションの要素として使えません。クラスがミュータブルなオブジェクトを定義しており、 __eq__() メソッドを実装しているなら、 __hash__() を定義してはなりません。これは、ハッシュ可能コレクションの実装においてキーのハッシュ値がイミュータブルであることが要求されているからです (オブジェクトのハッシュ値が変化すると、誤ったハッシュバケツ: hash bucket に入ってしまいます)。

ユーザー定義クラスはデフォルトで __eq__()__hash__() メソッドを持っています。 このとき、(同一でない) すべてのオブジェクトは比較して異なり、 x.__hash__()x == yx is yhash(x) == hash(y) の両方を意味するような適切な値を返します。

__eq__() をオーバーライドしていて __hash__() を定義していないクラスは、暗黙的に None に設定された __hash__() を持ちます。クラスの __hash__() メソッドが None の場合、そのクラスのインスタンスのハッシュ値を取得しようとすると適切な TypeError が送出され、 isinstance(obj, collections.Hashable) をチェックするとハッシュ不能なものとして正しく認識されます。

__eq__() をオーバーライドしたクラスが親クラスからの __hash__() の 実装を保持したいなら、明示的に __hash__ = <ParentClass>.__hash__ を設定することで、それをインタプリタに伝えなければなりません。

__eq__() をオーバーライドしていないクラスがハッシュサポートを抑制したい場合、クラス定義に __hash__ = None を含めてください。クラス自身で明示的に TypeError を送出する __hash__() を定義すると、 isinstance(obj, collections.Hashable) 呼び出しで誤ってハッシュ可能と識別されるでしょう。

注釈

デフォルトでは、文字列、バイト列、datetime オブジェクトの __hash__() 値は予測不可能なランダム値で “ソルト化” されます。 ハッシュ値は単独の Python プロセス内では定数であり続けますが、Python を繰り返し起動する毎に、予測できなくなります。

これは、慎重に選ばれた入力で辞書挿入の最悪性能 O(n^2) 複雑性を悪用することで引き起こされるサービス妨害 (denial-of-service) に対する保護を目的とするものです。詳細は http://www.ocert.org/advisories/ocert-2011-003.html を参照してください。

ハッシュ値の変更は、辞書、集合、その他のマップ型のイテレーション順序に影響します。 Python はこの順序付けを保証していません (そして通常 32-bit と 64-bit の間でも異なります)。

PYTHONHASHSEED も参照してください。

バージョン 3.3 で変更: ハッシュのランダム化がデフォルトで有効になりました。

object.__bool__(self)

真理値テストや組み込み演算 bool() を実装するために呼び出されます; False または True を返さなければなりません。このメソッドが定義されていないとき、 __len__() が定義されていれば呼び出され、その結果が非 0 であれば真とみなされます。クラスが __len__()__bool__() も定義していないければ、そのクラスのインスタンスはすべて真とみなされます。

3.3.2. 属性値アクセスをカスタマイズする

以下のメソッドを定義して、クラスインスタンスへの属性値アクセス (属性値の使用、属性値への代入、 x.name の削除) の意味をカスタマイズすることができます。

object.__getattr__(self, name)

属性値の検索を行った結果、通常の場所に属性値が見つからなかった場合 (すなわち、 self のインスタンス属性でなく、かつクラスツリーにも見つからなかった場合) に呼び出されます。このメソッドは (計算された) 属性値を返すか、 AttributeError 例外を送出しなければなりません。

なお、通常の過程で属性が見つかれば、 __getattr__() は呼び出されません。(これは、 __getattr__()__setattr__() が意図的に非対称にされている点です。) これは、効率のためと、こうしないと __getattr__() がインスタンスの他の属性値にアクセスする方法がなくなるためです。また、少なくともインスタンス変数に対しては、値をインスタンスの属性値辞書に挿入しないことで (代わりに他のオブジェクトに挿入することで)、属性値を完全に制御しているふりができます。実際に属性アクセスを完全に制御する方法は、以下の __getattribute__() メソッドを参照してください。

object.__getattribute__(self, name)

クラスのインスタンスに対する属性アクセスを実装するために、無条件に呼び出されます。クラスが __getattr__() も定義している場合、 __getattr__() は、 __getattribute__() で明示的に呼び出すか、 AttributeError 例外を送出しない限り呼ばれません。このメソッドは (計算された) 属性値を返すか、 AttributeError 例外を送出します。このメソッドが再帰的に際限なく呼び出されてしまうのを防ぐため、実装の際には常に、必要な属性全てへのアクセスで、例えば object.__getattribute__(self, name) のように基底クラスのメソッドを同じ属性名を使って呼び出さなければなりません。

注釈

言語構文や組み込み関数から暗黙に呼び出された特殊メソッドの検索では、このメソッドも回避されることがあります。 特殊メソッド検索 を参照してください。

object.__setattr__(self, name, value)

属性の代入が試みられた際に呼び出されます。これは通常の代入の過程 (すなわち、インスタンス辞書への値の代入) の代わりに呼び出されます。 name は属性名で、 value はその属性に代入する値です。

__setattr__() の中でインスタンス属性への代入が必要なら、基底クラスのこれと同じ名前のメソッドを呼び出さなければなりません。例えば、 object.__setattr__(self, name, value) とします。

object.__delattr__(self, name)

__setattr__() に似ていますが、代入ではなく値の削除を行います。このメソッドを実装するのは、オブジェクトにとって del obj.name が意味がある場合だけにしなければなりません。

object.__dir__(self)

オブジェクトに dir() が呼び出されたときに呼び出されます。シーケンスが返されなければなりません。 dir() は返されたシーケンスをリストに変換し、ソートします。

3.3.2.1. デスクリプタ (descriptor) の実装

以下のメソッドは、このメソッド含むクラス (いわゆる デスクリプタ(descriptor) クラス) のインスタンスが オーナー (owner) クラスに存在するときにのみ適用されます。 (デスクリプタは、オーナーのクラス辞書か、その親のいずれかのクラス辞書になければなりません。) 以下の例での “属性” は、名前がオーナークラスの __dict__ のプロパティ (porperty) のキーであるような属性を指します。

object.__get__(self, instance, owner)

オーナークラスの属性を取得する (クラス属性へのアクセス) 際や、オーナークラスのインスタンスの属性を取得する (インスタンス属性へのアクセス) 場合に呼び出されます。 owner は常にオーナークラスです。一方、 instance は属性へのアクセスを仲介するインスタンスか属性が owner を介してアクセスされる場合は None になります。このメソッドは (計算された) 属性値を返すか、 AttributeError 例外を送出しなければなりません。

object.__set__(self, instance, value)

オーナークラスのインスタンス instance 上の属性を新たな値 value に設定する際に呼び出されます。

object.__delete__(self, instance)

オーナークラスのインスタンス instance 上の属性を削除する際に呼び出されます。

3.3.2.2. デスクリプタの呼び出し

一般にデスクリプタとは、特殊な “束縛に関する動作 (binding behaviour)” をもつオブジェクト属性のことです。デスクリプタは、デスクリプタプロトコル (descriptor protocol) のメソッド: __get__(), __set__(), および __delete__() を使って、属性アクセスをオーバーライドしているものです。これらのメソッドのいずれかがオブジェクトに対して定義されている場合、オブジェクトはデスクリプタであるといいます。

属性アクセスのデフォルトの動作は、オブジェクトの辞書から値を取り出したり、値を設定したり、削除したりするというものです。例えば、 a.x による属性の検索では、まず a.__dict__['x'] 、次に type(a).__dict__['x'] 、そして type(a) の基底クラスでメタクラスでないものに続く、といった具合に連鎖が起こります。

しかし、検索対象の値が、デスクリプタメソッドのいずれかを定義しているオブジェクトであれば、Python はデフォルトの動作をオーバーライドして、代わりにデスクリプタメソッドを呼び出します。先述の連鎖の中のどこでデスクリプタメソッドが呼び出されるかは、どのデスクリプタメソッドが定義されていて、どのように呼び出されたかに依存します。

デスクリプタ呼び出しの基点となるのは、属性名への束縛 (binding) 、すなわち a.x です。引数がどのようにデスクリプタに結合されるかは a に依存します:

直接呼び出し

最も単純で、かつめったに使われない呼び出し操作は、コード中で直接デスクリプタメソッドの呼び出し: x.__get__(a) を行うというものです。

インスタンス束縛

オブジェクトインスタンスへ束縛すると、 a.x は呼び出し type(a).__dict__['x'].__get__(a, type(a)) に変換されます。

クラス束縛

クラスへ束縛すると、 A.x は呼び出し A.__dict__['x'].__get__(None, A) に変換されます。

super 束縛

asuper のインスタンスである場合、束縛 super(B, obj).m() を行うとまず A 、続いて B に対して obj.__class_.__mro__ を検索し、次に呼び出し: A.__dict__['m'].__get__(obj, obj.__class__) でデスクリプタを呼び出します。

インスタンス束縛では、デスクリプタ呼び出しの優先順位はどのデスクリプタが定義されているかに依存します。データデスクリプタは、 __get__()__set__()__delete__() の任意の組合せを定義することができます。 __get__() が定義されない場合には、その属性にアクセスすると、そのオブジェクトのインスタンス辞書にその値がある場合を除けば、デスクリプタオブジェクト自身が返ってきます。デスクリプタが __set__()__delete__() またはそのどちらかを定義していれば、データデスクリプタとなります; もし両方とも定義しなければ、非データデスクリプタです。通常、データデスクリプタでは、 __get__()__set__() を定義し、一方、非データデスクリプタには __get__() メソッドしかありません。インスタンス辞書内で属性値が再定義されても、データデスクリプタは常にこの値をオーバーライドします。対照的に、非データデスクリプタの場合には、属性値はインスタンス側でオーバーライドされます。

(staticmethod()classmethod() を含む) Python メソッドは、非データデスクリプタとして実装されています。その結果、インスタンスではメソッドを再定義したりオーバーライドできます。このことにより、個々のインスタンスが同じクラスの他のインスタンスと互いに異なる動作を獲得することができます。

property() 関数はデータデスクリプタとして実装されています。従って、インスタンスはあるプロパティの動作をオーバーライドすることができません。

3.3.2.3. __slots__

デフォルトでは、クラスのインスタンスは属性を保存するための辞書を持っています。これは、ほとんどインスタンス変数を持たないオブジェクトでは領域の無駄です。大量のインスタンスを生成するとき、この記憶領域の消費量は深刻になり得ます。

このデフォルトの設定は、クラス定義中で __slots__ を定義することでオーバーライドできます。 __slots_ 宣言はインスタンス変数のシーケンスを取り、各々のインスタンス上には、各変数の値を記憶するのに必要な量だけの記憶領域を確保します。各々のインスタンスに対して __dict__ が生成されることがないので、記憶領域が節約されます。

object.__slots__

このクラス変数には、インスタンスが用いる変数名を表す、文字列、イテラブル、または文字列のシーケンスを代入できます。この変数がクラスで定義されていれば、 __slots__ は、各インスタンスに対して宣言された変数に必要な記憶領域を確保し、 __dict____weakref__ が自動的に生成されないようにします。

3.3.2.3.1. __slots__ を利用する際の注意
  • __slots__ を持たないクラスから継承する場合、 __dict__ 属性は常にアクセス可能なので、サブクラスで __slots__ を定義しても意味がありません。

  • __dict__ 変数がない場合、 __slots__ に列挙されていない新たな変数をインスタンスに代入することはできません。列挙されていない変数名を使って代入しようとした場合、 AttributeError が送出されます。新たな変数を動的に代入したいのなら、 __slots__ を宣言する際に '__dict__' を変数名のシーケンスに追加してください。

  • __slots__ を定義しているクラスの各インスタンスに __weakref__ 変数がない場合、インスタンスに対する弱参照 (weak reference) はサポートされません。弱参照のサポートが必要なら、 __slots__ を宣言する際に '__weakref__' を変数名のシーケンスに追加してください。

  • __slots__ は、クラスのレベルで各変数に対するデスクリプタ (デスクリプタ (descriptor) の実装 を参照) を使って実装されます。その結果、 __slots__ に定義されているインスタンス変数のデフォルト値はクラス属性を使って設定できなくなっています; そうしないと、デスクリプタによる代入をクラス属性が上書きしてしまうからです。

  • __slots__ 宣言が動作するのは、定義が行われたクラスだけに限られています。その結果、サブクラスでは、 __slots__ を定義しない限り __dict__ を持つことになります。

  • あるクラスで、基底クラスですでに定義されているスロットを定義した場合、基底クラスのスロットで定義されているインスタンス変数は (デスクリプタを基底クラスから直接取得しない限り) アクセスできなくなります。これにより、プログラムの趣意が不定になってしまいます。将来は、この問題を避けるために何らかのチェックが追加されるかもしれません。

  • 空でない __slots__ は、 intbytestuple のような “可変長の” 組み込み型から派生したクラスでは動作しません。

  • __slots__ には、文字列でない反復可能オブジェクトを代入することができます。辞書型も使うことができます; しかし将来、辞書の各キーに相当する値に何らかの特殊な意味が割り当てられるかもしれません。

  • __class__ への代入は、両方のクラスが同じ __slots__ を持っているときのみ動作します。

3.3.3. クラス生成をカスタマイズする

デフォルトでは、クラスは type() を使って構築されます。 クラス本体は新しい名前空間で実行され、クラス名が type(name, bases, dict) の結果にローカルに束縛されます。

クラス生成プロセスはカスタマイズできます。そのためにはクラス定義行で metaclass キーワード引数を渡すか、そのような引数を含む既存のクラスから継承します。次の例で MyClassMySubclass は両方とも Meta のインスタンスです:

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass

クラス定義の中で指定された他のキーワード引数は、後述するすべてのメタクラス操作に渡されます。

クラス定義が実行される際に、以下のステップが生じます:

  • 適切なメタクラスが決定される

  • クラスの名前空間が準備される

  • クラスの本体が実行される

  • クラスオブジェクトが作られる

3.3.3.1. 適切なメタクラスの決定

クラス定義に対して適切なメタクラスは、以下のように決定されます:

  • ベースクラスも明示的なメタクラスも指定されなかった場合、 type() が使われます

  • 明示的にメタクラスが指定され、それが type() のインスタンス でない 場合、それが直接メタクラスとして使われます。

  • type() のインスタンスが明示的にメタクラスとして指定されたり、ベースクラスが定義されている場合、最も派生的なメタクラスが使われます。

最も派生的なメタクラスは、 (もしあれば) 明示的に指定されたメタクラスと、指定されたすべてのベースクラスのメタクラスから選ばれます。最も派生的なメタクラスは、これらのメタクラス候補のすべてのサブタイプであるようなものです。メタクラス候補のどれもその基準を満たさなければ、クラス定義は TypeError で失敗します。

3.3.3.2. クラスの名前空間の準備

適切なメタクラスが識別されたら、次にクラスの名前空間が準備されます。メタクラスに __prepare__ 属性がある場合、それは、 namespace = metaclass.__prepare__(name, bases, **kwds) として呼ばれます (ここで追加のキーワード引数は、もしあればクラス定義から来ます)。

メタクラスに __prepare__ 属性がない場合、クラスの名前空間は空の dict() インスタンスとして初期化されます。

参考

PEP 3115 - Metaclasses in Python 3000

__prepare__ 名前空間フックの導入

3.3.3.3. クラス本体の実行

クラス本体が (大まかには) exec(body, globals(), namespace) として実行されます。通常の呼び出しと exec() の重要な違いは、クラス定義が関数内部で行われる場合、レキシカルスコープによってクラス本体 (任意のメソッドを含む) が現在のスコープと外側のスコープから名前を参照できるという点です。

しかし、クラス定義が関数内部で行われる時でさえ、クラス内部で定義されたメソッドはクラススコープで定義された名前を見ることはできません。クラス変数はインスタンスメソッドかクラスメソッドの最初のパラメータを通してアクセスしなければならず、静的メソッドからは全くアクセスできません。

3.3.3.4. クラスオブジェクトの作成

クラス本体の実行によってクラスの名前空間が初期化されたら、 metaclass(name, bases, namespace, **kwds) を呼び出すことでクラスオブジェクトが作成されます (ここで渡される追加のキーワードは __prepare__ に渡されるものと同じです)。

このクラスオブジェクトは、 super() の無引数形式によって参照されるものです。 __class__ は、クラス本体中のメソッドが __class__ または super のいずれかを参照している場合に、コンパイラによって作成される暗黙のクロージャー参照です。これは、メソッドに渡された最初の引数に基づいて現在の呼び出しを行うために使用されるクラスまたはインスタンスが識別される一方、 super() の無引数形式がレキシカルスコープに基づいて定義されているクラスを正確に識別することを可能にします。

クラスオブジェクトが作成された後で、 (もしあれば) クラス定義に含まれているクラスデコレータにクラスオブジェクトが渡され、その結果生じるオブジェクトが定義されたクラスとしてローカルの名前空間に束縛されます。

参考

PEP 3135 - New super

暗黙の __class__ クロージャ参照について記述しています。

3.3.3.5. メタクラスの例

メタクラスは限りない潜在的利用価値を持っています。これまで試されてきたアイデアには、ログ記録、インタフェースのチェック、 自動デリゲーション、自動プロパティ生成、プロキシ、フレームワーク、そして自動リソースロック/同期といったものがあります。

ここに、 collections.OrderedDict を使い、クラスのメンバが定義された順序を記憶するメタクラスの例を挙げます:

class OrderedClass(type):

     @classmethod
     def __prepare__(metacls, name, bases, **kwds):
        return collections.OrderedDict()

     def __new__(cls, name, bases, namespace, **kwds):
        result = type.__new__(cls, name, bases, dict(namespace))
        result.members = tuple(namespace)
        return result

class A(metaclass=OrderedClass):
    def one(self): pass
    def two(self): pass
    def three(self): pass
    def four(self): pass

>>> A.members
('__module__', 'one', 'two', 'three', 'four')

この A のクラス定義が実行されたとき、処理はメタクラスの __prepare__() を呼び出すことから始まり、それは空の collections.OrderedDict を返します。このマッピングは、 A のメソッドと属性を、クラス文の本体内で定義された順に記録します。一旦この定義が実行されると、順序付き辞書は完全に登録され、メタクラスの __new__() メソッドが呼び出されます。このメソッドは新しい型を構築し、順序付き辞書のキーを members と呼ばれる属性に保存します。

3.3.4. インスタンスのカスタマイズとサブクラスチェック

以下のメソッドは組み込み関数 isinstance()issubclass() のデフォルトの動作を上書きするのに利用します。

特に、 abc.ABCMeta メタクラスは、抽象基底クラス (ABCs) を”仮想基底クラス (virtual base classes)” として、他の ABC を含む、任意のクラスや (組み込み型を含む) 型に追加するために、これらのメソッドを実装しています。

class.__instancecheck__(self, instance)

instance が (直接、または間接的に) class のインスタンスと考えられる場合に true を返します。定義されていれば、 isinstance(instance, class) の実装のために呼び出されます。

class.__subclasscheck__(self, subclass)

subclass が (直接、または間接的に) class のサブクラスと考えられる場合に true を返します。定義されていれば、 issubclass(subclass, class) の実装のために呼び出されます。

なお、これらのメソッドは、クラスの型 (メタクラス) 上で検索されます。実際のクラスにクラスメソッドとして定義することはできません。これは、インスタンスそれ自体がクラスであるこの場合にのみ、インスタンスに呼び出される特殊メソッドの検索と一貫しています。

参考

PEP 3119 - Introducing Abstract Base Classes

抽象基底クラス (abc モジュールを参照) を言語に追加する文脈においての動機から、 __instancecheck__()__subclasscheck__() を通して、 isinstance()issubclass() に独自の動作をさせるための仕様の記述があります。

3.3.5. 呼び出し可能オブジェクトをエミュレートする

object.__call__(self[, args...])

インスタンスが関数として “呼ばれた” 際に呼び出されます; このメソッドが定義されている場合、 x(arg1, arg2, ...)x.__call__(arg1, arg2, ...) を短く書いたものになります。

3.3.6. コンテナをエミュレートする

以下に挙げるメソッドを定義することで、コンテナオブジェクトを実装できます。 コンテナは通常は (リストやタプルのような) シーケンスや (辞書のような) マッピングですが、他のコンテナも同じように表現することができます。 最初のメソッド群はシーケンスもしくはマッピングを模倣するために使われます; 両者の違いは、シーケンスでキーとして使えるのは、 N をシーケンスの長さとして 0 <= k < N を満たす整数 k 、もしくは要素の範囲を定義するスライスオブジェクトです。 マッピングは、 Python の標準の辞書オブジェクトのメソッドと似た振る舞いをするメソッド keys()values()items()get()clear()setdefault()pop()popitem()copy()update() を提供することも推奨されています。 collections モジュールは、 MutableMapping 抽象基底クラスを提供し、 __getitem__()__setitem__()__delitem__()keys() という基礎となるメソッド群から前文で挙げたメソッドを作成するのを助けてくれます。 可変シーケンスは、 Python の標準のリストオブジェクトと同じように、メソッド append()count()index()extend()insert()pop()remove()reverse()sort() を提供すべきです。 最後に、シーケンス型は (連結を意味する) 加算と (繰り返しを意味する) 乗算を、以下に説明するメソッド __add__()__radd__()__iadd__()__mul__()__rmul__()__imul__() を定義して実装すべきです; そして、それ以外の数値演算子は定義すべきではありません。 マッピングとシーケンスは両方とも、効率の良い in 演算子が使えるように __contains__() メソッドを実装すべきです; マッピングでは in はマッピングのキーを検索すべきです; シーケンスでは値を検索すべきです。 マッピングもシーケンスも、コンテナの効率の良い反復処理ができるよう __iter__() メソッドを実装すべきです; マッピングでは __iter__()keys() と同じであるべきです; シーケンスでは値全体の反復処理を行うべきです。

object.__len__(self)

組み込み関数 len() を実装するために呼び出されます。オブジェクトの長さを整数 >= 0 で返さなければなりません。また、 __bool__() メソッドを定義しておらず、 __len__() メソッドが 0 を返すようなオブジェクトは、ブール演算コンテキストでは偽であるとみなされます。

注釈

スライシングは、以下の 3 メソッドによって排他的に行われます。次のような呼び出しは

a[1:2] = b

次のように翻訳され

a[slice(1, 2, None)] = b

以下も同様です。存在しないスライスの要素は None で埋められます。

object.__getitem__(self, key)

self[key] の値評価 (evaluation) を実現するために呼び出されます。シーケンスの場合、キーとして整数とスライスオブジェクトを受理できなければなりません。 (シーケンス型をエミュレートする場合) 負のインデックスの解釈は __getitem__() メソッド次第となります。 key が不適切な型であった場合、 TypeError を送出してもかまいません; (負のインデックス値に対して何らかの解釈を行った上で) key がシーケンスのインデックス集合外の値である場合、 IndexError を送出しなければなりません。マップ型の場合は、 key に誤りがある場合(コンテナに含まれていない場合)、 IndexError を送出しなければなりません。

注釈

for ループでは、シーケンスの終端を正しく検出できるようにするために、不正なインデックスに対して IndexError が送出されるものと期待しています。

object.__setitem__(self, key, value)

self[key] に対する代入を実現するために呼び出されます。 __getitem__() と同じ注意事項があてはまります。このメソッドを実装できるのは、あるキーに対する値の変更をサポートしているか、新たなキーを追加できるようなマップの場合と、ある要素を置き換えることができるシーケンスの場合だけです。不正な key に対しては、 __getitem__() メソッドと同様の例外の送出を行わなければなりません。

object.__delitem__(self, key)

self[key] の削除を実現するために呼び出されます。 __getitem__() と同じ注意事項があてはまります。このメソッドを実装できるのは、キーの削除をサポートしているマップの場合と、要素を削除できるシーケンスの場合だけです。不正な key に対しては、 __getitem__() メソッドと同様の例外の送出を行わなければなりません。

object.__iter__(self)

このメソッドは、コンテナに対してイテレータが要求された際に呼び出されます。このメソッドは、コンテナ内の全てのオブジェクトに渡って反復処理できるような、新たなイテレータオブジェクトを返さなければなりません。マッピングでは、コンテナ内のキーに渡って反復処理しなければならず、かつ keys() メソッドとしても利用できなければなりません。

イテレータオブジェクトでもこのメソッドを実装する必要があります; イテレータの場合、自分自身を返さなければなりません。イテレータオブジェクトに関するより詳細な情報は、 イテレータ型 を参照してください。

object.__reversed__(self)

reversed() 組み込み関数が逆方向イテレーションを実装するために、(存在すれば)呼び出します。コンテナ内の全要素を逆順にイテレートする、新しいイテレータを返すべきです。

__reversed__() メソッドが定義されていない場合、 reversed() 組込み関数は sequence プロトコル (__len__()__getitem__()) を使った方法にフォールバックします。 sequence プロトコルをサポートしたオブジェクトは、 reversed() よりも効率のいい実装を提供できる場合にのみ __reversed__() を定義するべきです。

メンバシップテスト演算子 (in および not in) は通常、シーケンスに渡る反復処理を使って実装されます。しかし、コンテナオブジェクトで以下の特殊メソッドを定義して、より効率的な実装を行ったり、オブジェクトがシーケンスでなくてもよいようにできます。

object.__contains__(self, item)

メンバシップテスト演算を実現するために呼び出されます。 itemself 内に存在する場合には真を、そうでない場合には偽を返さなければなりません。マップオブジェクトの場合、値やキーと値の組ではなく、キーに対するメンバシップテストを考えなければなりません。

__contains__() を定義しないオブジェクトに対しては、メンバシップテストはまず、 __iter__() を使った反復を試みます、次に古いシーケンス反復プロトコル __getitem__() を使います、 言語レファレンスのこの節 を参照して下さい。

3.3.7. 数値型をエミュレーションする

以下のメソッドを定義して、数値型オブジェクトをエミュレートすることができます。特定の種類の数値型ではサポートされていないような演算に対応するメソッド (非整数の数値に対するビット単位演算など) は、未定義のままにしておかなければなりません。

object.__add__(self, other)
object.__sub__(self, other)
object.__mul__(self, other)
object.__truediv__(self, other)
object.__floordiv__(self, other)
object.__mod__(self, other)
object.__divmod__(self, other)
object.__pow__(self, other[, modulo])
object.__lshift__(self, other)
object.__rshift__(self, other)
object.__and__(self, other)
object.__xor__(self, other)
object.__or__(self, other)

これらのメソッドは、二項算術演算 (+-*///%divmod()pow()**<<>>&^|) を実現するために呼び出されます。例えば、式 x + y は、 x__add__() メソッドをもつクラスのインスタンスであれば、 x.__add__(y) が呼び出されます。 __divmod__() メソッドは、 __floordiv__()__mod__() を使うのと等価にならなければなりません; __truediv__() と関連づける必要はありません。なお、組み込みの pow() 関数の三項演算子版をサポートするには、 __pow__() は、オプションとなる第三の引数を受け取れなくてはなりません。

こらのメソッドが渡された引き数に対する操作を提供していない場合には、 NotImplemented を送出しなければなりません。

object.__radd__(self, other)
object.__rsub__(self, other)
object.__rmul__(self, other)
object.__rtruediv__(self, other)
object.__rfloordiv__(self, other)
object.__rmod__(self, other)
object.__rdivmod__(self, other)
object.__rpow__(self, other)
object.__rlshift__(self, other)
object.__rrshift__(self, other)
object.__rand__(self, other)
object.__rxor__(self, other)
object.__ror__(self, other)

これらのメソッドは二項算術演算 (+-*//%divmod()pow()**<<>>&^|) の、被演算子が逆転した (reflected, swapped: 入れ替えられた) ものを実装するために呼び出されます。。これらの関数は、左側の被演算子が対応する演算をサポートしておらず、かつ両者の非演算子が異なる型の場合にのみ呼び出されます。 [2] 例えば、 y__rsub__() メソッドを持つクラスのインスタンスであるとして、 x.__sub__(y)NotImplemented を返すなら、式 x - y の評価に y.__rsub__(x) が呼び出されます。

ただし、三項演算子 pow()__rpow__() を呼ぶことはないので注意してください (型強制の規則が非常に難解になるからです)。

注釈

右側の被演算子の型が左側の被演算子の型のサブクラスであり、このサブクラスであるメソッドに対する逆転メソッドが定義されている場合には、左側の被演算子の非逆転メソッドが呼ばれる前に、このメソッドが呼ばれます。この振る舞いにより、サブクラスが親の操作をオーバーライドすることが可能になります。

object.__iadd__(self, other)
object.__isub__(self, other)
object.__imul__(self, other)
object.__itruediv__(self, other)
object.__ifloordiv__(self, other)
object.__imod__(self, other)
object.__ipow__(self, other[, modulo])
object.__ilshift__(self, other)
object.__irshift__(self, other)
object.__iand__(self, other)
object.__ixor__(self, other)
object.__ior__(self, other)

These methods are called to implement the augmented arithmetic assignments (+=, -=, *=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |=). These methods should attempt to do the operation in-place (modifying self) and return the result (which could be, but does not have to be, self). If a specific method is not defined, the augmented assignment falls back to the normal methods. For instance, if x is an instance of a class with an __iadd__() method, x += y is equivalent to x = x.__iadd__(y) . Otherwise, x.__add__(y) and y.__radd__(x) are considered, as with the evaluation of x + y. In certain situations, augmented assignment can result in unexpected errors (see なぜ加算はされるのに a_tuple[i] += [‘item’] は例外を送出するのですか?), but this behavior is in fact part of the data model.

object.__neg__(self)
object.__pos__(self)
object.__abs__(self)
object.__invert__(self)

単項算術演算 (-, +, abs() および ~) を実現するために呼び出されます。

object.__complex__(self)
object.__int__(self)
object.__float__(self)
object.__round__(self[, n])

組み込み関数 complex()int()float() 、および round() を実装するために呼び出されます。適切な型の値を返さなければなりません。

object.__index__(self)

operator.index() を実装するために呼び出されます。また、 (スライシングや、組み込みの bin()hex()oct() のように) Python が整数オブジェクトを必要とする場合には何処でも呼び出されます。整数を返さなければなりません。

3.3.8. with文とコンテキストマネージャ

コンテキストマネージャ(context manager) とは、 with 文の実行時にランタイムコンテキストを定義するオブジェクトです。コンテキストマネージャは、コードブロックを実行するために必要な入り口および出口の処理を扱います。コンテキストマネージャは通常、 with 文( with 文 の章を参照)により起動されますが、これらのメソッドを直接呼び出すことで起動することもできます。

コンテキストマネージャの代表的な使い方としては、様々なグローバル情報の保存および更新、リソースのロックとアンロック、ファイルのオープンとクローズなどが挙げられます。

コンテキストマネージャについてのさらなる情報については、 コンテキストマネージャ型 を参照してください。

object.__enter__(self)

コンテキストマネージャのの入り口で実行される処理です。 with 文は、文の as 節で規定された値を返すこのメソッドを呼び出します。

object.__exit__(self, exc_type, exc_value, traceback)

コンテキストマネージャの出口で実行される処理です。パラメータは、コンテキストが終了した原因となった例外について説明しています。コンテキストが例外を送出せず終了した場合は、全ての引き数に None が設定されます。

もし、例外が送出され、かつメソッドが例外を抑制したい場合(すなわち、例外が伝播されるのを防ぎたい場合)、このメソッドは True を返す必要があります。そうでなければ、このメソッドの終了後、例外は通常通り伝播することになります。

__exit__() メソッドは受け取った例外を再度送出すべきではありません。これは、呼び出し側の責任でおこなってください。

参考

PEP 0343 - The “with” statement

仕様、背景、および、Python with 文の例。

3.3.9. 特殊メソッド検索

カスタムクラスでは、特殊メソッドの暗黙の呼び出しは、オブジェクトのインスタンス辞書ではなく、オブジェクトの型で定義されているときにのみ正しく動作することが保証されます。この動作のため、以下のコードは例外を送出します:

>>> class C:
...     pass
...
>>> c = C()
>>> c.__len__ = lambda: 5
>>> len(c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'C' has no len()

この動作の背景となる理由は、 __hash__()__repr__() といった type オブジェクトを含むすべてのオブジェクトで定義されている特殊メソッドにあります。これらのメソッドの暗黙の検索が通常の検索プロセスを使った場合、 type オブジェクト自体に対して実行されたときに失敗してしまいます:

>>> 1 .__hash__() == hash(1)
True
>>> int.__hash__() == hash(int)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor '__hash__' of 'int' object needs an argument

クラスの非結合メソッドをこのようにして実行しようとすることは、 ‘metaclass confusion’ と呼ばれることもあり、特殊メソッドを検索するときはインスタンスをバイパスすることで回避されます:

>>> type(1).__hash__(1) == hash(1)
True
>>> type(int).__hash__(int) == hash(int)
True

正確性のためにインスタンス属性をスキップするのに加えて、特殊メソッド検索はオブジェクトのメタクラスを含めて、 __getattribute__() メソッドもバイパスします:

>>> class Meta(type):
...    def __getattribute__(*args):
...       print("Metaclass getattribute invoked")
...       return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
...     def __len__(self):
...         return 10
...     def __getattribute__(*args):
...         print("Class getattribute invoked")
...         return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__()                 # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c)          # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c)                      # Implicit lookup
10

このように __getattribute__() 機構をバイパスすることで、特殊メソッドの扱いに関するある程度の自由度と引き換えに (特殊メソッドはインタプリタから一貫して実行されるためにクラスオブジェクトに設定 しなければならない)、インタープリタを高速化するための大きな余地が手に入ります。

脚注

[1]

特定の条件が満たされた場合、オブジェクトの type を変更することが できます 。これは、正しく扱われなかった場合にとても奇妙な動作を引き起こすので、一般的には良い考えではありません。

[2]

同じ型の操作に対しては、(__add__() のような)逆転できないメソッドが失敗した時と同じような想定のもと処理されます。これは、逆転したメソッドを呼び出すことができないからです。