3. データモデル¶
3.1. オブジェクト、値、および型¶
Python における オブジェクト (object) とは、データを抽象的に表したものです。Python プログラムにおけるデータは全て、オブジェクトまたはオブジェクト間の関係として表されます。(ある意味では、プログラムコードもまたオブジェクトとして表されます。これはフォン・ノイマン: Von Neumann の "プログラム記憶方式コンピュータ: stored program computer" のモデルに適合します。)
すべての属性は、同一性 (identity)、型、値をもっています。 同一性 は生成されたあとは変更されません。これはオブジェクトのアドレスのようなものだと考えられるかもしれません。 'is
' 演算子は2つのオブジェクトの同一性を比較します。 id()
関数は同一性を表す整数を返します。
CPython 実装の詳細: CPython では、id(x)
は x
が格納されているメモリ上のアドレスを返します。
オブジェクトの型はオブジェクトがサポートする操作 (例: len()
をサポートするか) と、オブジェクトが取りうる値を決定します。 type()
関数はオブジェクトの型 (型自体もオブジェクトです) を返します。同一性と同じく、オブジェクトの型(type) も変更不可能です。 [1]
オブジェクトによっては 値 を変更することが可能です。値を変更できるオブジェクトのことを mutable と呼びます。生成後に値を変更できないオブジェクトのことを immutable と呼びます。(mutable なオブジェクトへの参照を格納している immutableなコンテナオブジェクトの値は、その格納しているオブジェクトの値が変化した時に変化しますが、コンテナがどのオブジェクトを格納しているのかが変化しないのであれば immutable だと考えることができます。したがって、immutable かどうかは値が変更可能かどうかと完全に一致するわけではありません) オブジェクトが mutable かどうかはその型によって決まります。例えば、数値型、文字列型とタプル型のインスタンスは immutable で、dict や list は mutable です。
オブジェクトを明示的に破壊することはできません; しかし、オブジェクトに到達不能 (unreachable) になると、ガベージコレクション (garbage-collection) によって処理されます。実装では、ごみ収集を遅らせたり、全く行わないようにすることができます — 到達可能なオブジェクトをごみ収集処理してしまわないかぎり、どう実装するかは実装品質の問題です。
CPython 実装の詳細: 現在の CPython 実装では参照カウント(reference-counting) 方式を使っており、(オプションとして) 循環参照を行っているごみオブジェクトを遅延検出します。この実装ではほとんどのオブジェクトを到達不能になると同時に処理することができますが、循環参照を含むごみオブジェクトの収集が確実に行われるよう保証しているわけではありません。循環参照を持つごみオブジェクト収集の制御については、 gc
モジュールを参照してください。 CPython以外の実装は別の方式を使っており、CPythonも将来は別の方式を使うかもしれません。オブジェクトが到達不能になったときに即座に終了処理されることに頼らないでください (ですからファイルは必ず明示的に閉じてください)。
実装のトレース機能やデバッグ機能を使えば、通常は収集されてしまうようなオブジェクトを生存させることがあるので注意してください。また、 'try
…except
' 文を使って例外を捕捉できるようにすると、オブジェクトを生存させることがあります。
オブジェクトには、開かれたファイルやウィンドウといった、 "外部 (external) の" リソースへの参照を含むものがあります。これらのリソースは、オブジェクトがごみ収集された際に解放されるものと理解されていますが、ごみ収集が行われる保証はないので、こうしたオブジェクトは外部リソースを明示的に解放する方法、大抵は close()
メソッドも提供しています。こうしたオブジェクトは明示的に close するよう強く奨めます。この操作をする際には、'try
…finally
' 文や、 'with
' 文を使うと便利です。
他のオブジェクトに対する参照をもつオブジェクトもあります; これらは コンテナ (container) と呼ばれます。コンテナオブジェクトの例として、タプル、リスト、および辞書が挙げられます。オブジェクトへの参照自体がコンテナの値の一部です。ほとんどの場合、コンテナの値というと、コンテナに入っているオブジェクトの値のことを指し、それらオブジェクトのアイデンティティではありません; しかしながら、コンテナの変更可能性について述べる場合、今まさにコンテナに入っているオブジェクトのアイデンティティのことを指します。したがって、 (タプルのように) 変更不能なオブジェクトが変更可能なオブジェクトへの参照を含む場合、その値が変化するのは変更可能なオブジェクトが変更された時、ということになります。
型はオブジェクトの動作のほとんど全てに影響します。オブジェクトのアイデンティティが重要かどうかでさえ、ある意味では型に左右されます: 変更不能な型では、新たな値を計算するような操作を行うと、実際には同じ型と値を持った既存のオブジェクトへの参照を返すことがありますが、変更可能なオブジェクトではそのような動作は起こりえません。例えば、 a = 1; b = 1
とすると、 a
と b
は値 1 を持つ同じオブジェクトを参照するときもあるし、そうでないときもあります。これは実装に依存します。しかし、 c = []; d = []
とすると、 c
と d
はそれぞれ二つの異なった、互いに一意な、新たに作成された空のリストを参照することが保証されています。 (c = d = []
とすると、 c
と d
の両方に同じオブジェクトを代入します)
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進数表現を持つと想定されます。負の数は符号ビットが左に無限に延びているような錯覚を与える 2 の補数表現の変型で表されます。- ブール値 (
bool
) 真偽値の False と True を表します。
False
とTrue
を表す 2 つのオブジェクトのみがブール値オブジェクトです。ブール型は整数型の派生型であり、ほとんどの状況でそれぞれ 0 と 1 のように振る舞いますが、例外として文字列に変換されたときはそれぞれ"False"
および"True"
という文字列が返されます。
整数表現に関する規則は、負の整数を含むシフト演算やマスク演算において、最も有意義な解釈ができるように意図されています。
- ブール値 (
numbers.Real
(float
) (実数)この型は計算機レベルの倍精度浮動小数点数を表現します。表現可能な値の範囲やオーバーフローの扱いは計算機のアーキテクチャ(および、CやJavaによる実装)に従います。Pythonは単精度浮動小数点数をサポートしません。一般的に単精度浮動小数点数を使う理由はプロセッサーとメモリの使用を節約するためと説明されます。しかし、こうした節約はPythonでオブジェクトを扱う際のオーバーヘッドに比べれば微々たるものです。また、2種類の浮動小数点数型を持つことで複雑になる理由はありません。
numbers.Complex
(complex
)この型は、計算機レベルで倍精度とされている浮動小数点を 2 つ一組にして複素数を表現します。浮動小数点について述べたのと同じ性質が当てはまります。複素数
z
の実数部および虚数部は、それぞれ読み出し専用属性z.real
およびz.imag
で取り出すことができます。
- シーケンス型 (sequence)
この型は、有限の順序集合 (ordered set) を表現します。要素は非負の整数でインデクス化されています。組み込み関数
len()
を使うと、シーケンスの要素数を返します。シーケンスの長さが n の場合、インデクスは 0, 1, …, n -1 からなる集合です。シーケンス a の要素 i はa[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 全ての要素を選択します。シーケンスは、変更可能なものか、そうでないかで区別されています:
- 変更不能なシーケンス (immutable sequence)
変更不能なシーケンス型のオブジェクトは、一度生成されるとその値を変更することができません。 (オブジェクトに他のオブジェクトへの参照が入っている場合、参照されているオブジェクトは変更可能なオブジェクトでもよく、その値は変更される可能性があります; しかし、変更不能なオブジェクトが直接参照しているオブジェクトの集合自体は、変更することができません。)
以下の型は変更不能なシーケンス型です:
- 文字列型 (string)
文字列はUnicodeコードポイントを表現する値の配列です。文字列中のどのコードポイントも
U+0000 - U+10FFFF
の範囲で表現されることができます。Pythonはchar
型を持ちません。代わりに、文字列中のどのコードポイントも長さ ''1'' の文字列オブジェクトとして表現することができます。組み込み関数ord()
は文字列形式を0 - 10FFFFの範囲の整数に変換します。また、組み込み関数chr()
は0 - 10FFFF
の範囲の整数を対応する長さ1
の文字列に変換します。str.encode()
はテキストエンコーディングを使うことでstr
をbytes
に変換するために使うことができます。また、bytes.decode()
によりその逆が実行することができます。- タプル型 (tuple)
タプルの要素は任意の Python オブジェクトです。二つ以上の要素からなるタプルは、個々の要素を表現する式をカンマで区切って構成します。単一の要素からなるタプル (単集合 'singleton') を作るには、要素を表現する式の直後にカンマをつけます (単一の式だけではタプルを形成しません。これは、式をグループ化するのに丸括弧を使えるようにしなければならないからです)。要素の全くない丸括弧の対を作ると空のタプルになります。
- bytes
bytes オブジェクトは不変な配列です。要素は 8-bit バイトで、 0 <= x < 256 の範囲の整数で表現されます。 (
b'abc'
のような) bytes リテラルや組み込みのbytes()
コンストラクタを使って bytes オブジェクトを作成できます。また、 bytes オブジェクトはdecode()
メソッドを通して文字列にデコードできます。
- 変更可能なシーケンス型 (mutable sequence)
変更可能なシーケンスは、作成した後で変更することができます。変更可能なシーケンスでは、添字表記やスライス表記を使って指定された要素に代入を行うことができ、
del
(delete) 文を使って要素を削除することができます。Python に最初から組み込まれている変更可能なシーケンス型は、今のところ二つです:
- リスト型 (list)
リストの要素は任意の Python オブジェクトにできます。リストは、角括弧の中にカンマで区切られた式を並べて作ります。 (長さが 0 や 1 のシーケンスを作るために特殊な場合分けは必要ないことに注意してください。)
- バイト配列
bytearray オブジェクトは変更可能な配列です。組み込みの
bytearray()
コンストラクタによって作成されます。変更可能なことを除けば (つまりハッシュ化できない)、 byte array は変更不能なbytes
オブジェクトと同じインターフェースと機能を提供します。
拡張モジュール
array
や、collections
モジュールには、さらなるミュータブルなシーケンス型の例があります。
- 集合型
集合型は、順序のない、ユニークで不変なオブジェクトの有限集合を表現します。そのため、(配列の)添字を使ったインデックスアクセスはできません。ただし、イテレートは可能で、組み込み関数
len()
は集合の要素数を返します。集合型の一般的な使い方は、集合に属しているかの高速なテスト、シーケンスからの重複の排除、共通集合・和集合・差・対称差といった数学的な演算の計算です。集合の要素には、辞書のキーと同じ普遍性に関するルールが適用されます。数値型は通常の数値比較のルールに従うことに注意してください。もし2つの数値の比較結果が同値である(例えば、
1
と1.0
)なら、そのうちの1つのみを集合に含めることができます。現在、2つの組み込み集合型があります:
- 集合型
可変な集合型です。組み込みの
set()
コンストラクタで作成され、後からadd()
などのいくつかのメソッドで更新できます。- Frozen set 型
不変な集合型です。組み込みの
frozenset()
コンストラクタによって作成されます。 frozenset は不変でハッシュ可能(hashable)なので、別の集合型の要素になったり、辞書のキーにすることができます。
- マッピング型 (mapping)
任意のインデクス集合でインデクス化された、オブジェクトからなる有限の集合を表現します。添字表記
a[k]
は、k
でインデクス指定された要素をa
から選択します; 選択された要素は式の中で使うことができ、代入やdel
文の対象にすることができます。組み込み関数len()
は、マッピング内の要素数を返します。Python に最初から組み込まれているマッピング型は、今のところ一つだけです:
- 辞書型 (dictionary)
ほぼ任意の値でインデクスされたオブジェクトからなる有限の集合を表します。 キー (key) として使えない値の唯一の型は、リストや辞書、そしてオブジェクトの同一性でなく値で比較されるその他の変更可能な型です。 これは、辞書型を効率的に実装する上で、キーのハッシュ値が不変である必要があるためです。 数値型をキーに使う場合、キー値は通常の数値比較における規則に従います: 二つの値が等しくなる場合 (例えば
1
と1.0
)、互いに同じ辞書のエントリを表すインデクスとして使うことができます。辞書は変更可能な型です; 辞書は
{...}
表記で生成します (辞書表現 を参照してください)。拡張モジュール
dbm.ndbm
、dbm.gnu
は、collections
モジュールのように、別のマッピング型の例を提供しています。
- 呼び出し可能型 (callable type)
関数呼び出し操作 (呼び出し (call) 参照) を行うことができる型です:
- ユーザ定義関数 (user-defined function)
ユーザ定義関数オブジェクトは、関数定義を行うことで生成されます (関数定義 参照)。関数は、仮引数 (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()
の定義を含むクラス、x
をC
のインスタンスとすると、x.f(1)
の呼び出しはC.f(x, 1)
の呼び出しと同じです。クラスメソッドオブジェクトからインスタンスメソッドオブジェクトが導出される際、
__self__
に記憶されている "クラスインスタンス" は実際はクラスそのものなので、x.f(1)
やC.f(1)
の呼び出しは、根底にある関数をf
としてf(C,1)
の呼び出しと等価です。なお、関数オブジェクトからインスタンスメソッドオブジェクトへの変換は、インスタンスから属性が取り出されるたびに行われます。場合によっては、属性をローカル変数に代入しておき、そのローカル変数を呼び出すようにするのが効果的な最適化になります。また、上記の変換はユーザ定義関数に対してのみ行われます; その他の呼び出し可能オブジェクト (および呼び出し可能でない全てのオブジェクト) は、変換されずに取り出されます。それから、クラスインスタンスの属性になっているユーザ定義関数は、束縛メソッドに変換されません; 変換されるのは、関数がクラスの属性である場合 だけ です。
- ジェネレータ関数 (generator function)
yield
文 (yield 文 の節を参照) を使う関数もしくはメソッドを ジェネレータ関数 と呼びます。そのような関数が呼び出されたときは常に、関数の本体を実行するのに使えるイテレータオブジェクトを返します: イテレータのiterator.__next__()
メソッドを呼び出すと、yield
文を使って値が提供されるまで関数を実行します。関数のreturn
文を実行するか終端に達したときは、StopIteration
例外が送出され、イテレータが返すべき値の最後まで到達しています。- コルーチン関数 (coroutine function)
async def
を使用して定義された関数やメソッドを コルーチン関数 (coroutine function) と呼びます。 呼び出された時、そのような関数は coroutine オブジェクトを返します。 コルーチン関数はasync with
やasync for
文だけでなくawait
式を持つことが出来ます。 コルーチンオブジェクト を参照してください。- 非同期ジェネレータ関数 (asynchronous generator function)
async def
を使って定義され、yield
文を使用している関数やメソッドを asynchronous generator function と呼びます。 そのような関数は、呼び出されたとき、非同期イテレータオブジェクトを返します。 このオブジェクトはasync for
文で関数の本体を実行するのに使えます。Calling the asynchronous iterator’s
aiterator.__anext__()
method will return an awaitable which when awaited will execute until it provides a value using theyield
expression. When the function executes an emptyreturn
statement or falls off the end, aStopAsyncIteration
exception is raised and the asynchronous iterator will have reached the end of the set of values to be yielded.- 組み込み関数 (built-in function)
組み込み関数オブジェクトはC関数へのラッパーです。 組み込み関数の例は
len()
やmath.sin()
(math
は標準の組み込みモジュール) です。 引数の数や型は C 関数で決定されています。 読み出し専用の特殊属性:__doc__
は関数のドキュメンテーション文字列です。 ドキュメンテーションがない場合はNone
になります;__name__
は関数の名前です;__self__
はNone
に設定されています (組み込みメソッドの節も参照してください);__module__
は、関数が定義されているモジュールの名前です。 モジュール名がない場合はNone
になります。- 組み込みメソッド (built-in method)
実際には組み込み関数を別の形で隠蔽したもので、こちらの場合には C 関数に渡される何らかのオブジェクトを非明示的な外部引数として持っています。組み込みメソッドの例は、 alist をリストオブジェクトとしたときの
alist.append()
です。この場合には、読み出し専用の属性__self__
は alist で表されるオブジェクトになります。- クラス
- クラスは呼び出し可能です。そのオブジェクトは通常、そのクラスの新たなインスタンスのファクトリとして振舞いますが、
__new__()
をオーバーライドして、バリエーションを持たせることもできます。呼び出しに使われた引数は、__new__()
と、典型的な場合では__init__()
に渡され、新たなインスタンスの初期化に使われます。 - クラスのインスタンス
- 任意のクラスのインスタンスは、クラスで
__call__()
メソッドを定義することで呼び出し可能になります。
- モジュール (module)
モジュールは Python コードの基礎的な組織単位で、
import
文あるいはimportlib.import_module()
や組み込みの__import__()
のような関数を呼び出すことで起動される import system によって作成されます (import
を参照)。モジュールオブジェクトは、辞書オブジェクト (これは、モジュール内で定義された関数の__globals__
属性から参照される辞書です) で実装された名前空間を持っています。属性の参照は、この辞書の検索に翻訳されます。例えば、m.x
はm.__dict__["x"]
と等価です。モジュールオブジェクトは、モジュールの初期化に使われるコードオブジェクトを含んでいません (初期化が終わればもう必要ないからです)。属性の代入を行うと、モジュールの名前空間辞書の内容を更新します。例えば、
m.x = 1
はm.__dict__["x"] = 1
と同じです。定義済みの (書き込み可能な) 属性:
__name__
はモジュールの名前です;__doc__
は関数のドキュメンテーション文字列です。ドキュメンテーションがない場合はNone
になります;__annotations__
(オプショナル) はモジュールの本体を実行しているときに収集した 変数アノテーション が入った辞書です; モジュールがファイルからロードされた場合、__file__
はロードされたモジュールファイルのパス名です。インタプリタに静的にリンクされている C モジュールのような特定の種類のモジュールでは、__file__
属性は存在しないかもしれません; 共有ライブラリから動的にロードされた拡張モジュールの場合、この属性は 共有ライブラリファイルのパス名になります。読み出し専用の特殊属性:
__dict__
はモジュールの名前空間で、辞書オブジェクトです。CPython 実装の詳細: CPython がモジュール辞書を削除する方法により、モジュール辞書が生きた参照を持っていたとしてもその辞書はモジュールがスコープから外れた時に削除されます。これを避けるには、辞書をコピーするか、辞書を直接使っている間モジュールを保持してください。
- カスタムクラス型
カスタムクラス型は通常、クラス定義 (クラス定義 参照) で生成されます。クラスは辞書オブジェクトで実装された名前空間を持っています。クラス属性の参照は、この辞書に対する探索 (lookup) に翻訳されます。例えば、
C.x
はC.__dict__["x"]
に翻訳されます (ただし、属性参照の意味を変えられる幾つかのフックがあります)。属性がこの探索で見つからないとき、その基底クラスで探索が続けられます。基底クラスのこの探索は、C3 メソッド解決順序 (MRO=method resolution order) を利用していて、複数の継承経路が共通の祖先につながる「ダイアモンド」継承構造があっても正しく動作します。 C3 MRO についてのより詳細な情報は、 2.3リリースに付属するドキュメント https://www.python.org/download/releases/2.3/mro/ にあります。When a class attribute reference (for class
C
, say) would yield a class method object, it is transformed into an instance method object whose__self__
attributes isC
. When it would yield a static method object, it is transformed into the object wrapped by the static method object. See section デスクリプタ (descriptor) の実装 for another way in which attributes retrieved from a class may differ from those actually contained in its__dict__
.クラス属性を代入すると、そのクラスの辞書だけが更新され、基底クラスの辞書は更新しません。
クラスオブジェクトを呼び出す (上記を参照) と、クラスインスタンスを生成します (下記を参照)。
特殊属性:
__name__
はクラス名です;__module__
はクラスが定義されたモジュール名です;__dict__
はクラスが持つ名前空間が入った辞書です;__bases__
は基底クラスからなるタプルで、基底クラスのリストに表れる順序で並んでいます;__doc__
はクラスのドキュメント文字列で、未定義の場合は None です;__annotations__
(オプショナル) はクラスの本体を実行しているときに収集した 変数アノテーション が入った辞書です。- クラスインスタンス (class instance)
クラスインスタンスは、クラスオブジェクト (上記参照) を呼び出して生成します。 クラスインスタンスは辞書で実装された名前空間を持っており、属性参照の時にはまずこの辞書が探索されます。 ここで属性が見つからず、インスタンスのクラスにその名前の属性があるときは、続けてクラス属性を検索します。 見つかったクラス属性がユーザ定義関数オブジェクトだった場合、クラスインスタンスを
__self__
属性とするインスタンスメソッドオブジェクトに変換します。 静的メソッドオブジェクトやクラスメソッドオブジェクトも同様に変換されます; 上記の "クラス" を参照してください。 デスクリプタ (descriptor) の実装 節を参照すると、また別の理由でインスタンスを通してクラスから取り出した属性と実際に__dict__
に保存されているものが異なることがあるのが分かります。 クラス属性が見つからず、かつオブジェクトのクラスが__getattr__()
メソッドを持っている場合は、探索の義務を果たすためにこのメソッドが呼び出されます。属性の代入や削除を行うと、インスタンスの辞書を更新しますが、クラスの辞書を更新することはありません。クラスで
__setattr__()
や__delattr__()
メソッドが定義されている場合、直接インスタンスの辞書を更新する代わりにこれらのメソッドが呼び出されます。クラスインスタンスは、ある特定の名前のメソッドを持っている場合、数値型やシーケンス型、あるいはマップ型のように振舞うことができます。 特殊メソッド名 を参照してください。
- I/O オブジェクト (ファイルオブジェクトの別名)
file object は開かれたファイルを表します。ファイルオブジェクトを作るための様々なショートカットがあります:
open()
組み込み関数、os.popen()
、os.fdopen()
、ソケットオブジェクトのmakefile()
メソッド (あるいは拡張モジュールから提供される他の関数やメソッド) 。オブジェクト
sys.stdin
、sys.stdout
およびsys.stderr
は、インタプリタの標準入力、標準出力、および標準エラー出力ストリームに対応するファイルオブジェクトに初期化されます。これらはすべてテキストモードで開かれ、io.TextIOBase
抽象クラスによって定義されたインタフェースに従います。- 内部型 (internal type)
インタプリタが内部的に使っているいくつかの型は、ユーザに公開されています。これらの定義は将来のインタプリタのバージョンでは変更される可能性がありますが、ここでは記述の完全性のために触れておきます。
- コードオブジェクト
コードオブジェクトは バイトコンパイルされた (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
になります。
- フレーム (frame) オブジェクト
フレームオブジェクトは実行フレーム (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 命令とも) を実装できます。フレームオブジェクトはメソッドを一つサポートします:
-
frame.
clear
()¶ このメソッドはフレームが保持しているローカル変数への参照を全て削除します。 また、フレームがジェネレータに属していた場合は、ジェネレータにも終了処理が行われます。 これによってフレームオブジェクトを含んだ循環参照が解消されるようになります (例えば、例外を捕捉し、後で使うためにトレースバックを保存する場合)。
フレームが現在実行中の場合
RuntimeError
が送出されます。バージョン 3.4 で追加.
-
- トレースバック (traceback) オブジェクト
トレースバックオブジェクトは例外のスタックトレースを表します。トレースバックオブジェクトは例外が発生した際に生成されます。例外ハンドラの検索が実行スタックを戻っていく際、戻ったレベル毎に、トレースバックオブジェクトが現在のトレースバックの前に挿入されます。例外ハンドラに入ると、スタックトレースをプログラム側で利用できるようになります。 (try 文 を参照。) トレースバックは、
sys.exc_info()
が返すタプルの三番目の要素として得られます。プログラムに適切なハンドラがないとき、スタックトレースは (うまく書式化されて) 標準エラーストリームに書き出されます; インタプリタが対話的に実行されている場合、sys.last_traceback
として得ることもできます。読み出し専用の特殊属性:
tb_next
はスタックトレース内の (例外の発生しているフレームに向かって) 次のレベルです。次のレベルが存在しない場合にはNone
になります;tb_frame
は現在のレベルにおける実行フレームを指します;tb_lineno
は例外の発生した行番号です;tb_lasti
は厳密な命令コードです。トレースバック内の行番号や最後に実行された命令は、try
文内で例外が発生し、かつ対応するexcept
節やfinally
節がない場合には、フレームオブジェクト内の行番号とは異なるかもしれません。- スライス (slice) オブジェクト
スライスオブジェクトは、
__getitem__()
メソッドのためのスライスを表すのに使われます。スライスオブジェクトは組み込みのslice()
関数でも生成されます。読み出し専用の特殊属性:
start
は下限です;stop
は上限です;step
はステップの値です; それぞれ省略された場合はNone
となっています。これらの属性は任意の型を持てます。スライスオブジェクトはメソッドを一つサポートします:
-
slice.
indices
(self, length)¶ このメソッドは単一の整数引数 length を取り、スライスオブジェクトが length 要素のシーケンスに適用されたときに表現する、スライスに関する情報を計算します。このメソッドは 3 つの整数からなるタプルを返します; それぞれ start および stop のインデックスと、step すなわちスライスのまたぎ幅です。インデックス値がないか、範囲外の値であれば、通常のスライスと変わらないやりかたで扱われます。
-
- 静的メソッド (static method) オブジェクト
- 静的メソッドは、上で説明したような関数オブジェクトからメソッドオブジェクトへの変換を阻止するための方法を提供します。静的メソッドオブジェクトは他の何らかのオブジェクト、通常はユーザ定義メソッドオブジェクトを包むラッパです。静的メソッドをクラスやクラスインスタンスから取得すると、実際に返されるオブジェクトはラップされたオブジェクトになり、それ以上は変換の対象にはなりません。静的メソッドオブジェクトは通常呼び出し可能なオブジェクトをラップしますが、静的オブジェクト自体は呼び出すことができません。静的オブジェクトは組み込みコンストラクタ
staticmethod()
で生成されます。 - クラスメソッドオブジェクト
- クラスメソッドオブジェクトは、静的メソッドオブジェクトに似て、別のオブジェクトを包むラッパであり、そのオブジェクトをクラスやクラスインスタンスから取り出す方法を代替します。このようにして取得したクラスメソッドオブジェクトの動作については、上の "ユーザ定義メソッド (user-defined method)" で説明されています。クラスメソッドオブジェクトは組み込みのコンストラクタ
classmethod()
で生成されます。
3.3. 特殊メソッド名¶
クラスは、特殊な名前のメソッドを定義して、特殊な構文 (算術演算や添え字表記、スライス表記など) による特定の演算を実装できます。これは、Python の演算子オーバロード (operator overloading) へのアプローチです。これにより、クラスは言語の演算子に対する独自の振る舞いを定義できます。例えば、あるクラスが __getitem__()
という名前のメソッドを定義しており、 x
がこのクラスのインスタンスであるとすると、 x[i]
は type(x).__getitem__(x, i)
とほぼ等価です。特に注釈のない限り、適切なメソッドが定義されていないとき、このような演算を試みると例外 (たいていは AttributeError
か TypeError
) が送出されます。
特殊メソッドに None
を設定することは、それに対応する演算が利用できないことを意味します。
例えば、クラスの __iter__()
を None
に設定した場合、そのクラスはイテラブルにはならず、そのインスタンスに対し iter()
を呼び出すと (__getitem__()
に処理が戻されずに) TypeError
を送出します。 [2]
組み込み型をエミュレートするクラスを実装するときは、模範とされるオブジェクトにとって意味がある範囲に実装をとどめるのが重要です。例えば、あるシーケンスは個々の要素の取得はきちんと動くかもしれませんが、スライスの展開が意味をなさないかもしれません。 (W3C のドキュメントオブジェクトモデルにある NodeList
インターフェースがその一例です。)
3.3.1. 基本的なカスタマイズ¶
-
object.
__new__
(cls[, ...])¶ クラス cls の新しいインスタンスを作るために呼び出されます。
__new__()
は静的メソッドで (このメソッドは特別扱いされているので、明示的に静的メソッドと宣言する必要はありません)、インスタンスを生成するよう要求されているクラスを第一引数にとります。残りの引数はオブジェクトのコンストラクタの式 (クラスの呼び出し文) に渡されます。__new__()
の戻り値は新しいオブジェクトのインスタンス (通常は cls のインスタンス) でなければなりません。典型的な実装では、クラスの新たなインスタンスを生成するときには
super().__new__(cls[, ...])
に適切な引数を指定してスーパクラスの__new__()
メソッドを呼び出し、新たに生成されたインスタンスに必要な変更を加えてから返します。__new__()
が cls のインスタンスを返した場合、__init__(self[, ...])
のようにしてインスタンスの__init__()
が呼び出されます。このとき、 self は新たに生成されたインスタンスで、残りの引数は__new__()
に渡された引数と同じになります。__new__()
が cls のインスタンスを返さない場合、インスタンスの__init__()
メソッドは呼び出されません。__new__()
の主な目的は、変更不能な型 (int, str, tuple など) のサブクラスでインスタンス生成をカスタマイズすることにあります。また、クラス生成をカスタマイズするために、カスタムのメタクラスでよくオーバーライドされます。
-
object.
__init__
(self[, ...])¶ インスタンスが (
__new__()
によって) 生成された後、それが呼び出し元に返される前に呼び出されます。引数はクラスのコンストラクタ式に渡したものです。基底クラスとその派生クラスがともに__init__()
メソッドを持つ場合、派生クラスの__init__()
メソッドは基底クラスの__init__()
メソッドを明示的に呼び出して、インスタンスの基底クラス部分が適切に初期化されること保証しなければなりません。例えば、super().__init__([args...])
。__new__()
と__init__()
は連携してオブジェクトを構成する (__new__()
が作成し、__init__()
がそれをカスタマイズする) ので、__init__()
から非None
値を返してはいけません; そうしてしまうと、実行時にTypeError
が送出されてしまいます。
-
object.
__del__
(self)¶ インスタンスが破棄されるときに呼び出されます。 これはファイナライザや (適切ではありませんが) デストラクタとも呼ばれます。 基底クラスが
__del__()
メソッドを持っている場合は、派生クラスの__del__()
メソッドは何であれ、基底クラスの__del__()
メソッドを明示的に呼び出して、インスタンスの基底クラス部分をきちんと確実に削除しなければなりません。__del__()
メソッドが破棄しようとしているインスタンスへの新しい参照を作り、破棄を送らせることは (推奨されないものの) 可能です。 これはオブジェクトの 復活 と呼ばれます。 復活したオブジェクトが再度破棄される直前に__del__()
が呼び出されるかどうかは実装依存です; 現在の CPython の実装では最初の一回しか呼び出されません。インタプリタが終了したときに、残存しているオブジェクトの
__del__()
メソッドが呼び出される保証はありません。注釈
del x
は直接x.__del__()
を呼び出しません — 前者はx
の参照カウントを 1 つ減らし、後者はx
の参照カウントが 0 まで落ちたときのみ呼び出されます。CPython 実装の詳細: It is possible for a reference cycle to prevent the reference count of an object from going to zero. In this case, the cycle will be later detected and deleted by the cyclic garbage collector. A common cause of reference cycles is when an exception has been caught in a local variable. The frame’s locals then reference the exception, which references its own traceback, which references the locals of all frames caught in the traceback.
参考
gc
モジュールのドキュメント。警告
Due to the precarious circumstances under which
__del__()
methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed tosys.stderr
instead. In particular:__del__()
can be invoked when arbitrary code is being executed, including from any arbitrary thread. If__del__()
needs to take a lock or invoke any other blocking resource, it may deadlock as the resource may already be taken by the code that gets interrupted to execute__del__()
.__del__()
can be executed during interpreter shutdown. As a consequence, the global variables it needs to access (including other modules) may already have been deleted or set toNone
. Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted; if no other references to such globals exist, this may help in assuring that imported modules are still available at the time when the__del__()
method is called.
-
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.
__format__
(self, format_spec)¶ format()
組み込み関数、さらには フォーマット済み文字列リテラル の評価、str.format()
メソッドによって呼び出され、オブジェクトの "フォーマット化された (formatted)" 文字列表現を作ります。format_spec
引数は、 必要なフォーマット化オプションの記述を含む文字列です。format_spec
引数の解釈は、__format__()
を実装する型によりますが、 ほとんどのクラスは組み込み型のいずれかにフォーマット化を委譲したり、 同じようなフォーマット化オプション構文を使います。標準のフォーマット構文の解説は、 書式指定ミニ言語仕様 を参照してください。
戻り値は文字列オブジェクトでなければなりません。
バージョン 3.4 で変更: 空でない文字列が渡された場合
object
自身の __format__ メソッドはTypeError
を送出します。
-
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<y
はx.__lt__(y)
を呼び出します;x<=y
はx.__le__(y)
を呼び出します;x==y
はx.__eq__(y)
を呼び出します;x!=y
はx.__ne__(y)
を呼び出します;x>y
はx.__gt__(y)
を呼び出します;x>=y
はx.__ge__(y)
を呼び出します。拡張比較メソッドは与えられた引数のペアに対する演算を実装していないときに、 シングルトン
NotImplemented
を返すかもしれません。 慣例として、正常に比較が行われたときにはFalse
かTrue
を返します。 しかし、これらのメソッドは任意の値を返すことができるので、比較演算子がブール値のコンテキスト (たとえばif
文の条件部分) で使われた場合、 Python はその値に対してbool()
を呼び出して結果の真偽を判断します。デフォルトでは
__ne__()
はNotImplemented
でない限り__eq__()
に委譲して結果を反転させます。比較演算の間には他に暗黙の関係はありません。例えば(x<y or x==y)
が真であることは暗黙的にx<=y
ではありません。元となる一つの演算から自動的に順序の演算を生成するにはfunctools.total_ordering()
を参照してください。カスタムの比較演算をサポートしていて、辞書のキーに使うことができるハッシュ可能(hashable) オブジェクトを作るときの重要な注意点について、
__hash__()
のドキュメント内に書かれているので参照してください。これらのメソッドには (左引数が演算をサポートしないが、右引数はサポートする場合に用いられるような) 引数を入れ替えたバージョンは存在しません。 むしろ、
__lt__()
と__gt__()
は互いの反射、__le__()
と__ge__()
は互いの反射、および__eq__()
と__ne__()
はそれら自身の反射です。 被演算子が異なる型で右の被演算子の型が左の被演算子の直接的または間接的サブクラスの場合、右被演算子の反射されたメソッドが優先されます。 そうでない場合左の被演算子のメソッドが優先されます。 仮想サブクラス化は考慮されません。
-
object.
__hash__
(self)¶ 組み込みの
hash()
関数や、set
,frozenset
,dict
のようなハッシュを使ったコレクション型の要素に対する操作から呼び出されます。__hash__()
は整数を返さなければなりません。 このメソッドに必要な性質は、比較結果が等しいオブジェクトは同じハッシュ値を持つということです; オブジェクトを比較するときでも利用される要素をタプルに詰めてハッシュ値を計算することで、それぞれの要素のハッシュ値を混合することをおすすめします。def __hash__(self): return hash((self.name, self.nick, self.color))
注釈
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 == y
がx is y
とhash(x) == hash(y)
の両方を意味するような適切な値を返します。__eq__()
をオーバーライドしていて__hash__()
を定義していないクラスでは、__hash__()
は暗黙的にNone
に設定されます。 クラスの__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, DoS) に対する保護です。 詳細は 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)¶ Called when the default attribute access fails with an
AttributeError
(either__getattribute__()
raises anAttributeError
because name is not an instance attribute or an attribute in the class tree forself
; or__get__()
of a name property raisesAttributeError
). This method should either return the (computed) attribute value or raise anAttributeError
exception.なお、通常の過程で属性が見つかれば、
__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. モジュールの属性値アクセスをカスタマイズする¶
より細かい粒度でのモジュールの動作 (属性やプロパティの設定など) のカスタマイズのために、モジュールオブジェクトの __class__
属性に types.ModuleType
のサブクラスが設定できます。
例えば次のようになります:
import sys
from types import ModuleType
class VerboseModule(ModuleType):
def __repr__(self):
return f'Verbose {self.__name__}'
def __setattr__(self, attr, value):
print(f'Setting {attr}...')
setattr(self, attr, value)
sys.modules[__name__].__class__ = VerboseModule
注釈
モジュールの __class__
を設定しても、影響があるのは属性アクセスの構文が使われる検索だけです – モジュールの globals への直接アクセスは (モジュール内のコードからとモジュールの globals のどちらでも) 影響を受けません。
バージョン 3.5 で変更: モジュールの属性 __class__
が書き込み可能になりました。
3.3.2.2. デスクリプタ (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 上の属性を削除する際に呼び出されます。
-
object.
__set_name__
(self, owner, name)¶ Called at the time the owning class owner is created. The descriptor has been assigned to name.
バージョン 3.6 で追加.
__objclass__
属性は inspect
モジュールによって解釈され、このオブジェクトが定義されたクラスを特定するのに使われます (この属性を適切に設定しておくと、動的なクラスの属性を実行時に調べる助けになります)。
呼び出される側にとっては、この属性で指定されたクラス (もしくはそのサブクラス) のインスタンスが1番目の位置引数として期待もしくは要求されていることが示せます (例えば、 CPython は束縛されていない C で実行されたメソッドにこの属性を設定します)。
3.3.2.3. デスクリプタの呼び出し¶
一般にデスクリプタとは、特殊な "束縛に関する動作 (binding behaviour)" をもつオブジェクト属性のことです。デスクリプタは、デスクリプタプロトコル (descriptor protocol) のメソッド: __get__()
, __set__()
, および __delete__()
を使って、属性アクセスをオーバーライドしているものです。これらのメソッドのいずれかがオブジェクトに対して定義されている場合、オブジェクトはデスクリプタであるといいます。
属性アクセスのデフォルトの動作は、オブジェクトの辞書から値を取り出したり、値を設定したり、削除したりするというものです。例えば、 a.x
による属性の検索では、まず a.__dict__['x']
、次に type(a).__dict__['x']
、そして type(a)
の基底クラスでメタクラスでないものに続く、といった具合に連鎖が起こります。
しかし、検索対象の値が、デスクリプタメソッドのいずれかを定義しているオブジェクトであれば、Python はデフォルトの動作をオーバーライドして、代わりにデスクリプタメソッドを呼び出します。先述の連鎖の中のどこでデスクリプタメソッドが呼び出されるかは、どのデスクリプタメソッドが定義されていて、どのように呼び出されたかに依存します。
デスクリプタ呼び出しの基点となるのは、属性名への束縛 (binding) 、すなわち a.x
です。引数がどのようにデスクリプタに結合されるかは a
に依存します:
- 直接呼び出し (Direct Call)
- 最も単純で、かつめったに使われない呼び出し操作は、コード中で直接デスクリプタメソッドの呼び出し:
x.__get__(a)
を行うというものです。 - インスタンス束縛 (Instance Binding)
- オブジェクトインスタンスへ束縛すると、
a.x
は呼び出しtype(a).__dict__['x'].__get__(a, type(a))
に変換されます。 - クラス束縛 (Class Binding)
- クラスへ束縛すると、
A.x
は呼び出しA.__dict__['x'].__get__(None, A)
に変換されます。 - super 束縛 (Super Binding)
a
がsuper
のインスタンスである場合、束縛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__()
メソッドしかありません。 __set__()
と __get__()
を定義したデータデスクリプタは、インスタンス辞書内で属性値が再定義されても、常にこの値をオーバーライドします。対照的に、非データデスクリプタの場合には、属性値はインスタンス側でオーバーライドされます。
(staticmethod()
や classmethod()
を含む) Python メソッドは、非データデスクリプタとして実装されています。その結果、インスタンスではメソッドを再定義したりオーバーライドできます。このことにより、個々のインスタンスが同じクラスの他のインスタンスと互いに異なる動作を獲得することができます。
property()
関数はデータデスクリプタとして実装されています。従って、インスタンスはあるプロパティの動作をオーバーライドすることができません。
3.3.2.4. __slots__¶
__slots__ allow us to explicitly declare data members (like properties) and deny the creation of __dict__ and __weakref__ (unless explicitly declared in __slots__ or available in a parent.)
__dict__ を使うのに比べて、節約できるメモリ空間はかなり大きいです。
-
object.
__slots__
¶ このクラス変数には、インスタンスが用いる変数名を表す、文字列、イテラブル、または文字列のシーケンスを代入できます。__slots__ は、各インスタンスに対して宣言された変数に必要な記憶領域を確保し、__dict__ と __weakref__ が自動的に生成されないようにします。
3.3.2.4.1. __slots__ を利用する際の注意¶
- When inheriting from a class without __slots__, the __dict__ and __weakref__ attribute of the instances will always be accessible.
- __dict__ 変数がない場合、 __slots__ に列挙されていない新たな変数をインスタンスに代入することはできません。列挙されていない変数名を使って代入しようとした場合、
AttributeError
が送出されます。新たな変数を動的に代入したいのなら、 __slots__ を宣言する際に'__dict__'
を変数名のシーケンスに追加してください。 - __slots__ を定義しているクラスの各インスタンスに __weakref__ 変数がない場合、インスタンスに対する弱参照 (weak reference) はサポートされません。弱参照のサポートが必要なら、 __slots__ を宣言する際に
'__weakref__'
を変数名のシーケンスに追加してください。 - __slots__ は、クラスのレベルで各変数に対するデスクリプタ (デスクリプタ (descriptor) の実装 を参照) を使って実装されます。その結果、 __slots__ に定義されているインスタンス変数のデフォルト値はクラス属性を使って設定できなくなっています; そうしないと、デスクリプタによる代入をクラス属性が上書きしてしまうからです。
- The action of a __slots__ declaration is not limited to the class where it is defined. __slots__ declared in parents are available in child classes. However, child subclasses will get a __dict__ and __weakref__ unless they also define __slots__ (which should only contain names of any additional slots).
- あるクラスで、基底クラスですでに定義されているスロットを定義した場合、基底クラスのスロットで定義されているインスタンス変数は (デスクリプタを基底クラスから直接取得しない限り) アクセスできなくなります。これにより、プログラムの趣意が不定になってしまいます。将来は、この問題を避けるために何らかのチェックが追加されるかもしれません。
- 空でない __slots__ は、
int
やbytes
やtuple
のような "可変長の" 組み込み型から派生したクラスでは動作しません。 - __slots__ には、文字列でない反復可能オブジェクトを代入することができます。辞書型も使うことができます; しかし将来、辞書の各キーに相当する値に何らかの特殊な意味が割り当てられるかもしれません。
- __class__ への代入は、両方のクラスが同じ __slots__ を持っているときのみ動作します。
- Multiple inheritance with multiple slotted parent classes can be used,
but only one parent is allowed to have attributes created by slots
(the other bases must have empty slot layouts) - violations raise
TypeError
.
3.3.3. クラス生成をカスタマイズする¶
クラスが他のクラスを継承するときに必ず、継承元のクラスの __init_subclass__ が呼び出されます。これを利用すると、サブクラスの挙動を変更するクラスを書くことができます。これは、クラスデコレータととても良く似ていますが、クラスデコレータが、それが適用された特定のクラスにのみに影響するのに対して、 __init_subclass__
は、もっぱら、このメソッドを定義したクラスの将来のサブクラスに適用されます。
-
classmethod
object.
__init_subclass__
(cls)¶ このメソッドは、それが定義されたクラスが継承された際に必ず呼び出されます。cls は新しいサブクラスです。もし、このメソッドがインスタンスメソッドとして定義されると、暗黙的にクラスメソッドに変換されます。
新しいクラスに与えられたキーワード引数は、親のクラスの
__init_subclass__
に渡されます。__init_subclass__
を利用している他のクラスとの互換性のために、以下のコードのように必要なキーワード引数を取得したら、他の引数は基底クラスに引き渡すべきです:class Philosopher: def __init_subclass__(cls, default_name, **kwargs): super().__init_subclass__(**kwargs) cls.default_name = default_name class AustralianPhilosopher(Philosopher, default_name="Bruce"): pass
object.__init_subclass__
のデフォルト実装は何も行いませんが、何らかの引数とともに呼び出された場合は、エラーを送出します。注釈
The metaclass hint
metaclass
is consumed by the rest of the type machinery, and is never passed to__init_subclass__
implementations. The actual metaclass (rather than the explicit hint) can be accessed astype(cls)
.バージョン 3.6 で追加.
3.3.3.1. メタクラス¶
デフォルトでは、クラスは type()
を使って構築されます。 クラス本体は新しい名前空間で実行され、クラス名が type(name, bases, namespace)
の結果にローカルに束縛されます。
クラス生成プロセスはカスタマイズできます。
そのためにはクラス定義行で metaclass
キーワード引数を渡すか、そのような引数を定義行に含む既存のクラスを継承します。
次の例で MyClass
と MySubclass
は両方とも Meta
のインスタンスです:
class Meta(type):
pass
class MyClass(metaclass=Meta):
pass
class MySubclass(MyClass):
pass
クラス定義の中で指定された他のキーワード引数は、後述するすべてのメタクラス操作に渡されます。
クラス定義が実行される際に、以下のステップが生じます:
- 適切なメタクラスが決定される
- クラスの名前空間が準備される
- クラスの本体が実行される
- クラスオブジェクトが作られる
3.3.3.2. 適切なメタクラスの決定¶
クラス定義に対して適切なメタクラスは、以下のように決定されます:
- ベースクラスも明示的なメタクラスも指定されなかった場合、
type()
が使われます - 明示的にメタクラスが指定され、それが
type()
のインスタンス でない 場合、それが直接メタクラスとして使われます type()
のインスタンスが明示的にメタクラスとして指定されたり、ベースクラスが定義されている場合、最も派生的なメタクラスが使われます
最も派生的なメタクラスは、(もしあれば) 明示的に指定されたメタクラスと、指定されたすべてのベースクラスのメタクラスから選ばれます。最も派生的なメタクラスは、これらのメタクラス候補のすべてのサブタイプであるようなものです。メタクラス候補のどれもその基準を満たさなければ、クラス定義は TypeError
で失敗します。
3.3.3.3. クラスの名前空間の準備¶
適切なメタクラスが識別されたら、次にクラスの名前空間が準備されます。メタクラスに __prepare__
属性がある場合、それは、namespace = metaclass.__prepare__(name, bases, **kwds)
として呼ばれます (ここで追加のキーワード引数は、もしあればクラス定義から来ます)。
メタクラスに __prepare__
属性がない場合、クラスの名前空間は空の 順序付きマッピングとして初期化されます。
参考
- PEP 3115 - Metaclasses in Python 3000
__prepare__
名前空間フックの導入
3.3.3.4. クラス本体の実行¶
クラス本体が (大まかには) exec(body, globals(), namespace)
として実行されます。通常の呼び出しと exec()
の重要な違いは、クラス定義が関数内部で行われる場合、レキシカルスコープによってクラス本体 (任意のメソッドを含む) が現在のスコープと外側のスコープから名前を参照できるという点です。
しかし、クラス定義が関数内部で行われる時でさえ、クラス内部で定義されたメソッドはクラススコープで定義された名前を見ることはできません。クラス変数はインスタンスメソッドかクラスメソッドの最初のパラメータからアクセスするか、次の節で説明する、暗黙的に静的スコープが切られている __class__
参照からアクセスしなければなりません。
3.3.3.5. クラスオブジェクトの作成¶
クラス本体の実行によってクラスの名前空間が初期化されたら、metaclass(name, bases, namespace, **kwds)
を呼び出すことでクラスオブジェクトが作成されます (ここで渡される追加のキーワードは __prepare__
に渡されるものと同じです)。
このクラスオブジェクトは、 super()
の無引数形式によって参照されるものです。 __class__
は、クラス本体中のメソッドが __class__
または super
のいずれかを参照している場合に、コンパイラによって作成される暗黙のクロージャー参照です。これは、メソッドに渡された最初の引数に基づいて現在の呼び出しを行うために使用されるクラスまたはインスタンスが識別される一方、 super()
の無引数形式がレキシカルスコープに基づいて定義されているクラスを正確に識別することを可能にします。
CPython 実装の詳細: In CPython 3.6 and later, the __class__
cell is passed to the metaclass
as a __classcell__
entry in the class namespace. If present, this must
be propagated up to the type.__new__
call in order for the class to be
initialised correctly.
Failing to do so will result in a DeprecationWarning
in Python 3.6,
and a RuntimeWarning
in the future.
デフォルトのメタクラス type
や最終的には type.__new__
を呼び出すメタクラスを使っているときは、クラスオブジェクトを作成した後に次のカスタム化の手順が起動されます:
- 最初に、
type.__new__
が__set_name__()
が定義されているクラスの名前空間にある全てのデスクリプタを収集します; - 次に、それら全ての
__set_name__
メソッドが、そのメソッドが定義されているクラス、およびそこに属するデスクリプタに割り当てられている名前を引数として呼び出されます; - 最後に、新しいクラスのメソッド解決順序ですぐ上に位置する親クラスで
__init_subclass__()
フックが呼び出されます。
クラスオブジェクトが作成された後には、クラス定義に含まれているクラスデコレータ (もしあれば) にクラスオブジェクトが渡され、デコレータが返すオブジェクトがここで定義されたクラスとしてローカルの名前空間に束縛されます。
新しいクラスが type.__new__
で生成されたときは、名前空間引数として与えられたオブジェクトは新しい順序付きのマッピングに複製され、元のオブジェクトは破棄されます。
新しく複製したものは読み出し専用のプロキシでラップされ、クラスオブジェクトの __dict__
属性になります。
参考
- PEP 3135 - New super
- 暗黙の
__class__
クロージャ参照について記述しています
3.3.3.6. メタクラスの例¶
メタクラスは限りない潜在的利用価値を持っています。これまで試されてきたアイデアには、列挙型、ログ記録、インタフェースのチェック、 自動デリゲーション、自動プロパティ生成、プロキシ、フレームワーク、そして自動リソースロック/同期といったものがあります。
ここに、 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 - 抽象基底クラスの導入
- 抽象基底クラス (
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 を返すようなオブジェクトは、ブール演算コンテキストでは偽とみなされます。CPython 実装の詳細: CPython では、オブジェクトの長さは最大でも
sys.maxsize
であることが要求されます。 長さがsys.maxsize
を越える場合、(len()
のような) いくつかの機能はOverflowError
を送出するでしょう。 真偽値としての判定でOverflowError
を送出しないようにするには、オブジェクトは meth:__bool__ メソッドを定義していなければなりません。
-
object.
__length_hint__
(self)¶ 呼び出して
operator.length_hint()
を実装します。 オブジェクトの推定される長さ (実際のものより長かったり短かったりするかもしれません) を返さなければなりません。 長さは 0 以上の整数でなければなりません。 このメソッドは純粋に最適化であり、正確性のために必要なものではありません。バージョン 3.4 で追加.
注釈
スライシングは、以下の 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 に誤りがある場合(コンテナに含まれていない場合)、KeyError
を送出しなければなりません。注釈
for
ループでは、シーケンスの終端を正しく検出できるようにするために、不正なインデクスに対してIndexError
が送出されるものと期待しています。
-
object.
__missing__
(self, key)¶ self[key]
の実装において辞書内にキーが存在しなかった場合に、 dict のサブクラスのためにdict
.__getitem__()
によって呼び出されます。
-
object.
__setitem__
(self, key, value)¶ self[key]
に対する代入を実装するために呼び出されます。__getitem__()
と同じ注意事項があてはまります。このメソッドを実装できるのは、あるキーに対する値の変更をサポートしているか、新たなキーを追加できるようなマップの場合と、ある要素を置き換えることができるシーケンスの場合だけです。不正な key に対しては、__getitem__()
メソッドと同様の例外の送出を行わなければなりません。
-
object.
__delitem__
(self, key)¶ self[key]
の削除を実装するために呼び出されます。__getitem__()
と同じ注意事項があてはまります。このメソッドを実装できるのは、キーの削除をサポートしているマップの場合と、要素を削除できるシーケンスの場合だけです。不正な key に対しては、__getitem__()
メソッドと同様の例外の送出を行わなければなりません。
-
object.
__iter__
(self)¶ このメソッドは、コンテナに対してイテレータが要求された際に呼び出されます。このメソッドは、コンテナ内の全てのオブジェクトに渡って反復処理できるような、新たなイテレータオブジェクトを返さなければなりません。マッピングでは、コンテナ内のキーに渡って反復処理しなければなりません。
イテレータオブジェクトでもこのメソッドを実装する必要があります; イテレータの場合、自分自身を返さなければなりません。イテレータオブジェクトに関するより詳細な情報は、 イテレータ型 を参照してください。
-
object.
__reversed__
(self)¶ reversed()
組み込み関数が逆方向イテレーションを実装するために、(存在すれば)呼び出します。コンテナ内の全要素を逆順にイテレートする、新しいイテレータを返すべきです。__reversed__()
メソッドが定義されていない場合、reversed()
組込み関数は sequence プロトコル (__len__()
と__getitem__()
) を使った方法にフォールバックします。 sequence プロトコルをサポートしたオブジェクトは、reversed()
よりも効率のいい実装を提供できる場合にのみ__reversed__()
を定義するべきです。
帰属テスト演算子 (in
および not in
) は通常、シーケンスに渡る反復処理を使って実装されます。しかし、コンテナオブジェクトで以下の特殊メソッドを定義して、より効率的な実装を行ったり、オブジェクトがシーケンスでなくてもよいようにできます。
-
object.
__contains__
(self, item)¶ 帰属テスト演算を実装するために呼び出されます。 item が self 内に存在する場合には真を、そうでない場合には偽を返さなければなりません。マップオブジェクトの場合、値やキーと値の組ではなく、キーに対する帰属テストを考えなければなりません。
__contains__()
を定義しないオブジェクトに対しては、メンバシップテストはまず、__iter__()
を使った反復を試みます、次に古いシーケンス反復プロトコル__getitem__()
を使います、 言語レファレンスのこの節 を参照して下さい。
3.3.7. 数値型をエミュレーションする¶
以下のメソッドを定義して、数値型オブジェクトをエミュレートすることができます。特定の種類の数値型ではサポートされていないような演算に対応するメソッド (非整数の数値に対するビット単位演算など) は、未定義のままにしておかなければなりません。
-
object.
__add__
(self, other)¶ -
object.
__sub__
(self, other)¶ -
object.
__mul__
(self, other)¶ -
object.
__matmul__
(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 が__add__()
メソッドのあるクラスのインスタンスである場合、式x + y
を評価するとx.__add__(y)
が呼ばれます。__divmod__()
メソッドは__floordiv__()
と__mod__()
を使用するのと等価でなければなりません。__truediv__()
と関連してはなりません。 組み込みのpow()
関数の三項のものがサポートされていなければならない場合、__pow__()
はオプションの第三引数を受け取るものとして定義されなければなりません。これらのメソッドのいずれかが渡された引数に対する操作を提供していない場合、
NotImplemented
を返すべきです。
-
object.
__radd__
(self, other)¶ -
object.
__rsub__
(self, other)¶ -
object.
__rmul__
(self, other)¶ -
object.
__rmatmul__
(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()
,**
,<<
,>>
,&
,^
,|
) の、被演算子が反射した (入れ替えられた) ものを実装します。 これらの関数は、左側の被演算子が対応する演算をサポートしておらず [3] 、非演算子が異なる型の場合にのみ呼び出されます。 [4] 例えば、 y が__rsub__()
メソッドのあるクラスのインスタンスである場合、 式x - y
を評価するとx.__sub__(y)
が NotImplemented を返すときはy.__rsub__(x)
が呼ばれます。ただし、三項演算子
pow()
が__rpow__()
を呼ぶことはないので注意してください (型強制の規則が非常に難解になるからです)。注釈
右側の被演算子の型が左側の被演算子の型のサブクラスであり、このサブクラスであるメソッドに対する反射メソッドが定義されている場合には、左側の被演算子の非反射メソッドが呼ばれる前に、このメソッドが呼ばれます。この振る舞いにより、サブクラスが親の演算をオーバーライドすることが可能になります。
-
object.
__iadd__
(self, other)¶ -
object.
__isub__
(self, other)¶ -
object.
__imul__
(self, other)¶ -
object.
__imatmul__
(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)¶ これらのメソッドを呼び出して累算算術代入 (
+=
,-=
,*=
,@=
,/=
,//=
,%=
,**=
,<<=
,>>=
,&=
,^=
,|=
) を実装します。 これらのメソッドは演算をインプレースで (self を変更する) 行うよう試み、その結果 (その必要はありませんが self でも構いません) を返さなければなりません。 特定のメソッドが定義されていない場合、その累算算術演算は通常のメソッドにフォールバックされます。 例えば x が__iadd__()
メソッドを持つクラスのインスタンスである場合、x += y
はx = x.__iadd__(y)
と等価です。 そうでない場合、x + y
の評価と同様にx.__add__(y)
とy.__radd__(x)
が考慮されます。 特定の状況では、累算代入は予期しないエラーに終わるかもしれません (なぜ加算はされるのに a_tuple[i] += ['item'] は例外を送出するのですか? を参照してください) が、この挙動は実際はデータモデルの挙動の一部です。
-
object.
__neg__
(self)¶ -
object.
__pos__
(self)¶ -
object.
__abs__
(self)¶ -
object.
__invert__
(self)¶ 呼び出して単項算術演算 (
-
,+
,abs()
および~
) を実装します。
-
object.
__complex__
(self)¶ -
object.
__int__
(self)¶ -
object.
__float__
(self)¶ 組み込み関数の
complex()
,int()
,float()
の実装から呼び出されます。 適切な型の値を返さなければなりません。
-
object.
__index__
(self)¶ 呼び出して
operator.index()
を実装します。 Python が数値オブジェクトを整数オブジェクトに損失なく変換する必要がある場合 (たとえばスライシングや、組み込みのbin()
、hex()
、oct()
関数) は常に呼び出されます。 このメソッドがあるとその数値オブジェクトが整数型であることが示唆されます。 整数を返さなければなりません。注釈
整数型クラスの一貫性を保つため、
__index__()
が定義された場合、__int__()
もまた定義されるべきであり、どちらも同じ値を返すべきです。
-
object.
__round__
(self[, ndigits])¶ -
object.
__trunc__
(self)¶ -
object.
__floor__
(self)¶ -
object.
__ceil__
(self)¶ 組み込み関数の
round()
とmath
モジュール関数のtrunc()
,floor()
,ceil()
の実装から呼び出されます。 ndigits が__round__()
に渡されない限りは、これらの全てのメソッドはIntegral
(たいていはint
) に切り詰められたオブジェクトの値を返すべきです。If
__int__()
is not defined then the built-in functionint()
falls back to__trunc__()
.
3.3.8. with文とコンテキストマネージャ¶
コンテキストマネージャ(context manager) とは、 with
文の実行時にランタイムコンテキストを定義するオブジェクトです。コンテキストマネージャは、コードブロックを実行するために必要な入り口および出口の処理を扱います。コンテキストマネージャは通常、 with
文( with 文 の章を参照)により起動されますが、これらのメソッドを直接呼び出すことで起動することもできます。
コンテキストマネージャの代表的な使い方としては、様々なグローバル情報の保存および更新、リソースのロックとアンロック、ファイルのオープンとクローズなどが挙げられます。
コンテキストマネージャについてのさらなる情報については、 コンテキストマネージャ型 を参照してください。
-
object.
__exit__
(self, exc_type, exc_value, traceback)¶ コンテキストマネージャの出口で実行される処理です。パラメータは、コンテキストが終了した原因となった例外について説明しています。コンテキストが例外を送出せず終了した場合は、全ての引き数に
None
が設定されます。もし、例外が送出され、かつメソッドが例外を抑制したい場合(すなわち、例外が伝播されるのを防ぎたい場合)、このメソッドは True を返す必要があります。そうでなければ、このメソッドの終了後、例外は通常通り伝播することになります。
__exit__()
メソッドは受け取った例外を再度送出すべきではありません。これは、呼び出し側の責任でおこなってください。
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__()
機構をバイパスすることで、特殊メソッドの扱いに関するある程度の自由度と引き換えに (特殊メソッドはインタプリタから一貫して実行されるためにクラスオブジェクトに設定 しなければならない)、インタープリタを高速化するための大きな余地が手に入ります。
3.4. コルーチン¶
3.4.1. 待機可能オブジェクト (Awaitable Object)¶
awaitable オブジェクトは一般的には __await__()
が実装されています。
async def
関数が返す Coroutine オブジェクトは待機可能です。
注釈
types.coroutine()
デコレータもしくは asyncio.coroutine()
でデコレータが付けられたジェネレータから返される generator iterator オブジェクトも待機可能ですが、 __await__()
は実装されていません。
-
object.
__await__
(self)¶ iterator を返さなければなりません。 このメソッドは awaitable オブジェクトを実装するのに使われるべきです。 簡単のために、
asyncio.Future
にはこのメソッドが実装され、await
式と互換性を持つようになっています。
バージョン 3.5 で追加.
参考
待機可能オブジェクトについてより詳しくは PEP 492 を参照してください。
3.4.2. コルーチンオブジェクト¶
Coroutine オブジェクトは awaitable オブジェクトです。
__await__()
を呼び出し、その返り値に対し反復処理をすることでコルーチンの実行を制御できます。
コルーチンの実行が完了し制御を戻したとき、イテレータは StopIteration
を送出し、その例外の value
属性に返り値を持たせます。
コルーチンが例外を送出した場合は、イテレータにより伝搬されます。
コルーチンから StopIteration
例外を外に送出すべきではありません。
コルーチンには以下に挙げるメソッドもあり、これらはジェネレータのメソッドからの類似です (ジェネレータ-イテレータメソッド を参照してください)。 ただし、ジェネレータと違って、コルーチンは反復処理を直接はサポートしていません。
バージョン 3.5.2 で変更: コルーチンで2回以上待機 (await) すると RuntimeError
となります。
-
coroutine.
send
(value)¶ コルーチンの実行を開始したり再開したりします。 value が
None
の場合は、__await__()
から返されたイテレータを進めるのと同等です。 value がNone
でない場合は、このコルーチンを一時停止させたイテレータのsend()
メソッドに処理を委任します。 結果 (返り値かStopIteration
かその他の例外) は、上で解説したような__await__()
の返り値に対して反復処理を行ったときと同じです。
-
coroutine.
throw
(type[, value[, traceback]])¶ コルーチンで指定された例外を送出します。 このメソッドは、イテレータにコルーチンを一時停止する
throw()
メソッドがある場合に処理を委任します。 そうでない場合には、中断した地点から例外が送出されます。 結果 (返り値かStopIteration
かその他の例外) は、上で解説したような__await__()
の返り値に対して反復処理を行ったときと同じです。 例外がコルーチンの中で捕捉されなかった場合、呼び出し元へ伝搬されます。
-
coroutine.
close
()¶ コルーチンが自分自身の後片付けをし終了します。 コルーチンが一時停止している場合は、コルーチンを一時停止させたイテレータに
close()
メソッドがあれば、まずはそれに処理を委任します。 そして一時停止した地点からGeneratorExit
が送出され、ただちにコルーチンが自分自身の後片付けを行います。 最後に、実行が開始されていなかった場合でも、コルーチンに実行が完了した印を付けます。コルーチンオブジェクトが破棄されるときには、上記の手順を経て自動的に閉じられます。
3.4.3. 非同期イテレータ (Asynchronous Iterator)¶
非同期イテラブル の __aiter__
の実装からは非同期のコードが呼べ、 非同期イテレータ の __anext__
メソッドからは非同期のコードが呼べます。
非同期イテレータは async for
文の中で使えます。
-
object.
__aiter__
(self)¶ 非同期イテレータ オブジェクトを返さなくてはなりません。
-
object.
__anext__
(self)¶ イテレータの次の値を返す 待機可能オブジェクト を返さなければなりません。 反復処理が終了したときには
StopAsyncIteration
エラーを送出すべきです。
非同期イテラブルオブジェクトの例:
class Reader:
async def readline(self):
...
def __aiter__(self):
return self
async def __anext__(self):
val = await self.readline()
if val == b'':
raise StopAsyncIteration
return val
バージョン 3.5 で追加.
注釈
バージョン 3.5.2 で変更: CPython 3.5.2 以降では、 __aiter__
は 非同期イテレータ を直接返せます。
awaitable オブジェクトを返すと PendingDeprecationWarning
が送出されます。
CPython 3.5.x での後方互換性のあるコードを書くときに推奨される方法は、 __aiter__
から待機可能オブジェクトを返し続けることです。
PendingDeprecationWarning を避け、コードの後方互換性を保ちたい場合は、次のデコレータが使えます:
import functools
import sys
if sys.version_info < (3, 5, 2):
def aiter_compat(func):
@functools.wraps(func)
async def wrapper(self):
return func(self)
return wrapper
else:
def aiter_compat(func):
return func
以下はプログラム例です:
class AsyncIterator:
@aiter_compat
def __aiter__(self):
return self
async def __anext__(self):
...
CPython 3.6 からは、 PendingDeprecationWarning
は DeprecationWarning
に置き換えられます。
CPython 3.7 では、 __aiter__
から待機可能オブジェクトを返すと RuntimeError
が送出されます。
3.4.4. 非同期コンテクストマネージャ (Asynchronous Context Manager)¶
非同期コンテキストマネージャ は、 __aenter__
メソッドと __aexit__
メソッド内部で実行を一時停止できる コンテキストマネージャ です。
非同期コンテキストマネージャは async with
文の中で使えます。
-
object.
__aenter__
(self)¶ このメソッドは文法的には
__enter__()
に似ていますが、 待機可能オブジェクト を返さなければならないところだけが異なります。
-
object.
__aexit__
(self, exc_type, exc_value, traceback)¶ このメソッドは文法的には
__exit__()
に似ていますが、 待機可能オブジェクト を返さなければならないところだけが異なります。
非同期コンテキストマネージャクラスの例:
class AsyncContextManager:
async def __aenter__(self):
await log('entering context')
async def __aexit__(self, exc_type, exc, tb):
await log('exiting context')
バージョン 3.5 で追加.
脚注
[1] | 特定の条件が満たされた場合、オブジェクトの type を変更することが できます 。これは、正しく扱われなかった場合にとても奇妙な動作を引き起こすので、一般的には良い考えではありません。 |
[2] | __hash__() , __iter__() , __reversed__() , __contains__() メソッドはこのような特別な扱われ方をします;
他の特殊メソッドも TypeError を送出するかもしれませんが、これは None が呼び出し可能でないという振る舞いに基づいた動作です。 |
[3] | ここでの "サポートしていない" というのは、クラスがそのメソッドを持っていないか、そのメソッドが NotImplemented を返すという意味です。
右の被演算子の対をなすメソッドへ処理を回したい場合には、メソッドに None を設定してはいけません—こうするとむしろ、処理を回すのを明示的に 妨げる という正反対の効果を生みます。 |
[4] | 同じ型の被演算子については、無反転のメソッド (たとえば __add__() ) が失敗した場合、その演算はサポートされていないとみなされます。
これは、反射したメソッドが呼び出されないためです。 |