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
というPythonで決められている名前でアクセスされます。 数値メソッドと拡張比較メソッドに渡された被演算子を処理する演算子が実装されていない場合、この値を返すべきです。 (この次にインタープリタは被演算子を反転させて演算をするか、その演算子に依存する他のフォールバックの処理を試します。) この処理では真偽値コンテキストでの評価はしてはいけません。詳細は 算術演算の実装 を参照してください。
バージョン 3.9 で変更:
NotImplemented
の評価は非推奨です。 現時点で真と評価されていてもDeprecationWarning
が出ます。 この警告は将来のバージョンの Python でTypeError
を送出します。- Ellipsis
この型には単一の値しかありません。この値を持つオブジェクトはただ一つしか存在しません。このオブジェクトはリテラル
...
またはPythonで決められている名前Ellipsis
でアクセスされます。真理値は真 (true)です。numbers.Number
数値リテラルによって作成されたり、算術演算や組み込みの算術関数によって返されるオブジェクトです。数値オブジェクトは変更不能です; 一度値が生成されると、二度と変更されることはありません。Python の数値オブジェクトはいうまでもなく数学で言うところの数値と強く関係していますが、コンピュータ内で数値を表現する際に伴う制限を受けています。
__repr__()
と__str__()
から計算された数値クラスの文字列表現には次のような特性があります:その文字列は、クラスコンストラクタに渡したときに、元の数値の値を持つオブジェクトを生成する有効な数値リテラルです。
できるなら、10を底として表現されます。
小数点の前にある 1 つのゼロを除いて、上に連なるゼロは表示されません。
小数点の後にある 1 つのゼロを除いて、下に連なるゼロは表示されません。
符号は数値が負数のときのみ表示されます。
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()
は文字列形式をU+0000 - U+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 は不変で ハッシュ可能 なので、別の集合型の要素になったり、辞書のキーにすることができます。
- マッピング型 (mapping)
任意のインデクス集合でインデクス化された、オブジェクトからなる有限の集合を表現します。添字表記
a[k]
は、k
でインデクス指定された要素をa
から選択します; 選択された要素は式の中で使うことができ、代入やdel
文の対象にすることができます。組み込み関数len()
は、マッピング内の要素数を返します。Python に最初から組み込まれているマッピング型は、今のところ一つだけです:
- 辞書型 (dictionary)
ほぼ任意の値でインデクスされたオブジェクトからなる有限の集合を表します。 キー (key) として使えない値の唯一の型は、リストや辞書、そしてオブジェクトの同一性でなく値で比較されるその他の変更可能な型です。 これは、辞書型を効率的に実装する上で、キーのハッシュ値が不変である必要があるためです。 数値型をキーに使う場合、キー値は通常の数値比較における規則に従います: 二つの値が等しくなる場合 (例えば
1
と1.0
)、互いに同じ辞書のエントリを表すインデクスとして使うことができます。辞書は挿入の順序を保持します。つまり、キーは辞書に追加された順番に生成されていきます。既存のキーを置き換えても、キーの順序は変わりません。キーを削除したのちに再挿入すると、元の場所ではなく辞書の最後に追加されます。
辞書は変更可能な型です; 辞書は
{...}
表記で生成します (辞書表示 を参照してください)。拡張モジュール
dbm.ndbm
、dbm.gnu
は、collections
モジュールのように、別のマッピング型の例を提供しています。バージョン 3.7 で変更: Pythonのバージョン3.6では、辞書は挿入順序を保持しませんでした。CPython 3.6では挿入順序は保持されましたが、それは策定された言語の仕様というより、その当時の実装の細部とみなされていました。
- 呼び出し可能型 (callable type)
関数呼び出し操作 (呼び出し (call) 参照) を行うことができる型です:
- ユーザ定義関数 (user-defined function)
ユーザ定義関数オブジェクトは、関数定義を行うことで生成されます (関数定義 参照)。関数は、仮引数 (formal parameter) リストと同じ数の要素が入った引数リストとともに呼び出されます。
特殊属性:
属性
意味
__doc__
関数のドキュメンテーション文字列で、ドキュメンテーションがない場合は
None
になります。サブクラスに継承されません。書き込み可能
関数の名前です。
書き込み可能
関数の qualified name です。
バージョン 3.3 で追加.
書き込み可能
__module__
関数が定義されているモジュールの名前です。モジュール名がない場合は
None
になります。書き込み可能
__defaults__
デフォルト値を持つ引数に対するデフォルト値が収められたタプルで、デフォルト値を持つ引数がない場合には
None
になります書き込み可能
__code__
コンパイルされた関数本体を表現するコードオブジェクトです。
書き込み可能
__globals__
関数のグローバル変数の入った辞書 (への参照) です --- この辞書は、関数が定義されているモジュールのグローバルな名前空間を決定します。
読み出し専用
任意の関数属性をサポートするための名前空間が収められています。
書き込み可能
__closure__
None
または関数の個々の自由変数 (引数以外の変数) に対して値を束縛しているセル (cell) 群からなるタプルになります。cell_contents
属性についての情報は下を参照してください。読み出し専用
__annotations__
パラメータの注釈が入った辞書です。辞書のキーはパラメータ名で、返り値の注釈がある場合は、
'return'
がそのキーとなります。この属性を使って作業することの情報は Annotations Best Practices を参照してください。書き込み可能
__kwdefaults__
キーワード専用パラメータのデフォルト値を含む辞書です。
書き込み可能
「書き込み可能」とラベルされている属性のほとんどは、代入された値の型をチェックします。
関数オブジェクトはまた、任意の属性を設定したり取得したりできます。この機能は、例えば関数にメタデータを付与したい場合などに使えます。関数の get や set には、通常のドット表記を使います。 現在の実装では、ユーザ定義の関数でのみ属性をサポートしているので注意して下さい。組み込み関数の属性は将来サポートする予定です。
セルオブジェクトは属性
cell_contents
を持っています。 これはセルの値を設定するのに加えて、セルの値を得るのにも使えます。関数定義に関するその他の情報は関数のコードオブジェクトから得られます。後述の内部型 (internal type) に関する説明を参照してください。
cell
型にはtypes
モジュールからアクセスできます。- インスタンスメソッド
インスタンスメソッドオブジェクトは、クラス、クラスインスタンスと任意の呼び出し可能オブジェクト (通常はユーザ定義関数) を結びつけます。
読み出し専用の特殊属性:
__self__
はクラスインスタンスオブジェクトで、__func__
は関数オブジェクトです;__doc__
はメソッドのドキュメンテーション文字列 (__func__.__doc__
と同じ) です;__name__
はメソッドの名前 (__func__.__name__
と同じ) です;__module__
はメソッドが定義されたモジュールの名前か、モジュール名がない場合はNone
になります。メソッドもまた、根底にある関数オブジェクトの任意の関数属性に (値の設定はできませんが) アクセスできます。
クラスの属性を (場合によってはそのクラスのインスタンスを介して) 取得するとき、その属性がユーザ定義の関数オブジェクトまたはクラスメソッドオブジェクトであれば、ユーザ定義メソッドオブジェクトが生成されることがあります。
クラスからインスタンスを経由してユーザ定義関数オブジェクトを取得することによってインスタンスメソッドオブジェクトが生成されたとき、
__self__
属性はそのインスタンスで、このメソッドオブジェクトは束縛されている (bound) といいます。新しいメソッドの__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
文で関数の本体を実行するのに使えます。非同期イテレータの
aiterator.__anext__
メソッドを呼び出すと、他の処理が待たされているときに、yield
式を使い値を提供するところまで処理を進める awaitable を返します。 その関数が空のreturn
文を実行する、もしくは処理の終わりに到達したときは、StopAsyncIteration
例外が送出され、非同期イテレータは出力すべき値の最後に到達したことになります。- 組み込み関数 (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__()
メソッドを定義することで呼び出し可能になります。
- モジュール
モジュールは Python コードの基礎的な構成単位で、
import
文あるいはimportlib.import_module()
や組み込みの__import__()
のような関数を呼び出すことで起動される import system によって作成されます。モジュールオブジェクトは、辞書オブジェクト (これは、モジュール内で定義された関数の__globals__
属性から参照される辞書です) で実装された名前空間を持っています。属性の参照は、この辞書の検索に翻訳されます。例えば、m.x
はm.__dict__["x"]
と等価です。モジュールオブジェクトは、モジュールの初期化に使われるコードオブジェクトを含んでいません (初期化が終わればもう必要ないからです)。属性の代入を行うと、モジュールの名前空間辞書の内容を更新します。例えば、
m.x = 1
はm.__dict__["x"] = 1
と同じです。定義済みの (書き込み可能な) 属性:
__name__
モジュールの名前。
__doc__
モジュールのドキュメントで、文字列か、もし利用できない場合は
None
です。__file__
ロードされたモジュールファイルのパス名です。インタプリタに静的にリンクされている C モジュールのような特定の種類のモジュールでは、
__file__
属性は存在しないかもしれません。共有ライブラリから動的にロードされた拡張モジュールの場合、この属性は 共有ライブラリファイルのパス名になります。__annotations__
モジュールの本体の実行中に収集した 変数アノテーション を格納する辞書です。
__annotations__
を利用するベストプラクティスについては、 アノテーションのHOWTO を参照してください。
読み出し専用の特殊属性:
__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/ にあります。クラス (
C
とします) 属性参照がクラスメソッドオブジェクトを返そうとするときには、 そのオブジェクトは__self__
属性がC
であるようなインスタンスメソッドオブジェクトに変換されます。 静的メソッドオブジェクトを返そうとするときには、静的メソッドオブジェクトでラップされたオブジェクトに変換されます。 デスクリプタ (descriptor) の実装 節を参照すると、また別の理由でクラスから取り出した属性と実際に__dict__
に保存されているものが異なることがあるのが分かります。クラス属性を代入すると、そのクラスの辞書だけが更新され、基底クラスの辞書は更新しません。
クラスオブジェクトを呼び出す (上記を参照) と、クラスインスタンスを生成します (下記を参照)。
特殊属性:
__name__
クラス名。
__module__
クラスが定義されているモジュールの名前。
__dict__
クラスの名前空間を格納している辞書。
__bases__
ベースクラスリストに現れる順序でベースクラスを格納しているタプル。
__doc__
クラスのドキュメントで、文字列か、もし未定義の場合は
None
です。__annotations__
クラスの本体の実行中に収集した 変数アノテーション を格納する辞書です。
__annotations__
を利用するベストプラクティスについては、 アノテーションのHOWTO を参照してください。
- クラスインスタンス (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 コード、別名 バイトコード を表現します。コードオブジェクトと関数オブジェクトの違いは、関数オブジェクトが関数のグローバル変数 (関数を定義しているモジュールのグローバル) に対して明示的な参照を持っているのに対し、コードオブジェクトにはコンテキストがないということです; また、関数オブジェクトではデフォルト引数値を記憶できますが、コードオブジェクトではできません (実行時に計算される値を表現するため)。関数オブジェクトと違い、コードオブジェクトは変更不可能で、変更可能なオブジェクトへの参照を (直接、間接に関わらず) 含みません。
読み出し専用の特殊属性:
co_name
は関数名、co_argcount
は位置引数 (位置専用引数とデフォルト値を持つ引数を含む) の総数、co_posonlyargcount
は位置専用引数 (デフォルト値を持つ引数を含む) の数、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_code
へのアクセスはobject.__getattr__
にobj
と"f_code"
を渡して行いますが、 監査イベント を送出します。特別な書き込み可能な属性:
f_trace
はNone
でない場合は、コードの実行中に様々なイベントで呼び出される関数です (デバッガが利用します)。 通常は、ソースの新しい行ごとにイベントが発行されますが、f_trace_lines
をFalse
に設定することでイベントの発行を無効化できます。実装は
f_trace_opcodes
をTrue
に設定して、命令コードごとのイベントの要求を許可している かもしれません 。 これは、トレース関数によって送出された例外がトレースされている関数に漏れ出た場合、未定義なインタープリタの振る舞いにつながるかもしれないことに注意してください。f_lineno
はフレーム中における現在の行番号です --- トレース関数 (trace function) 側でこの値に書き込みを行うと、指定した行にジャンプします (最下段の実行フレームにいるときのみ)。デバッガでは、 f_fileno を書き込むことで、ジャンプ命令 (Set Next Statement 命令とも) を実装できます。フレームオブジェクトはメソッドを一つサポートします:
-
frame.
clear
()¶ このメソッドはフレームが保持しているローカル変数への参照を全て削除します。 また、フレームがジェネレータに属していた場合は、ジェネレータにも終了処理が行われます。 これによってフレームオブジェクトを含んだ循環参照が解消されるようになります (例えば、例外を捕捉し、後で使うためにトレースバックを保存する場合)。
フレームが現在実行中の場合
RuntimeError
が送出されます。バージョン 3.4 で追加.
-
- トレースバック (traceback) オブジェクト
トレースバックオブジェクトは例外のスタックトレースを表現します。 トレースバックオブジェクトは例外が起きたときに暗黙的に作成されたり、
types.TracebackType
を呼び出して明示的にも作成されたりします。暗黙的に作成されたトレースバックでは、例外ハンドラの検索が実行スタックを戻っていく際、戻ったレベル毎に、トレースバックオブジェクトが現在のトレースバックの前に挿入されます。 例外ハンドラに入ると、スタックトレースをプログラム側で利用できるようになります。(try 文 を参照。) トレースバックは、
sys.exc_info()
が返すタプルの三番目の要素や、捕捉した例外の__traceback__
属性として得られます。プログラムに適切なハンドラがないとき、スタックトレースは (うまく書式化されて) 標準エラーストリームに書き出されます; インタプリタが対話的に実行されている場合、
sys.last_traceback
として得ることもできます。明示的に作成されたトレースバックでは、
tb_next
属性がリンクされスタックトレース全体を形成する方法の決定は、トレースバックの作成者に任されます。読み出し専用の特殊属性:
tb_frame
は現在のレベルにおける実行フレームを指します;tb_lineno
は例外の発生した行番号です;tb_lasti
は厳密な命令コードです。トレースバック内の行番号や最後に実行された命令は、try
文内で例外が発生し、かつ対応するexcept
節やfinally
節がない場合には、フレームオブジェクト内の行番号とは異なるかもしれません。tb_frame
へのアクセスはobject.__getattr__
にobj
と"tb_frame"
を渡して行いますが、 監査イベント を送出します。書き込み可能な特殊属性:
tb_next
はスタックトレースの次のレベル (例外が発生したフレームの方向) か、あるいは次のレベルが無い場合はNone
です。バージョン 3.7 で変更: トレースバックオブジェクトは Python コードから明示的にインスタンス化できるようになり、既存のインスタンスの
tb_next
属性は更新できるようになりました。- スライス (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__()
が 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
モジュールのドキュメント。警告
メソッド
__del__()
は不安定な状況で呼び出されるため、実行中に発生した例外は無視され、代わりにsys.stderr
に警告が表示されます。特に:__del__()
は、任意のコードが実行されているときに、任意のスレッドから呼び出せます。__del__()
で、ロックを取ったり、ブロックするリソースを呼び出したりする必要がある場合、__del__()
の実行により中断されたコードにより、そのリソースが既に取得されていて、デッドロックが起きるかもしれません。__del__()
は、インタプリタのシャットダウン中に実行できます。 従って、(他のモジュールも含めた) アクセスする必要があるグローバル変数はすでに削除されているか、None
に設定されているかもしれません。 Python は、単一のアンダースコアで始まる名前のグローバルオブジェクトは、他のグローバル変数が削除される前にモジュールから削除されることを保証します; そのようなグローバル変数への他からの参照が存在しない場合、__del__()
メソッドが呼ばれた時点で、インポートされたモジュールがまだ利用可能であることを保証するのに役立つかもしれません。
-
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
を送出します。バージョン 3.7 で変更:
object.__format__(x, '')
はformat(str(x), '')
ではなくstr(x)
と等価になりました。
-
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()
を呼び出して結果の真偽を判断します。is
から利用されるobject
の__eq__()
メソッドのデフォルト実装では、比較して偽となる場合に、次のコードのようにNotImplemented
を返します:True if x is y else NotImplemented
。__ne__()
メソッドは__eq__()
に処理を委譲し、NotImplemented
でない場合に結果を反転させます。他の比較演算子やデフォルトの実装には暗黙の関係はありません。例えば(x<y or x==y)
はx<=y
とはなりません。一つの元となる演算から比較演算子を自動生成するにはfunctools.total_ordering()
を参照してください。カスタムの比較演算をサポートしていて、辞書のキーに使うことができる ハッシュ可能 オブジェクトを作るときの重要な注意点について、
__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)"
を実行することです。If a class does not define an
__eq__()
method it should not define a__hash__()
operation either; if it defines__eq__()
but not__hash__()
, its instances will not be usable as items in hashable collections. If a class defines mutable objects and implements an__eq__()
method, it should not implement__hash__()
, since the implementation of hashable collections requires that a key's hash value is immutable (if the object's hash value changes, it will be in the wrong 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.abc.Hashable)
でチェックするとハッシュ不能なものとして正しく認識されます。__eq__()
をオーバーライドしたクラスが親クラスからの__hash__()
の 実装を保持したいなら、明示的に__hash__ = <ParentClass>.__hash__
を設定することで、それをインタプリタに伝えなければなりません。__eq__()
をオーバーライドしていないクラスがハッシュサポートを抑制したい場合、クラス定義に__hash__ = None
を含めてください。クラス自身で明示的にTypeError
を送出する__hash__()
を定義すると、isinstance(obj, collections.abc.Hashable)
呼び出しで誤ってハッシュ可能と識別されるでしょう。注釈
デフォルトでは、文字列とバイト列の
__hash__()
値は予測不可能なランダム値で "ソルト" されます。 ハッシュ値は単独の Python プロセス内では定数であり続けますが、Python を繰り返し起動する毎に、予測できなくなります。この目的は、慎重に選ばれた入力で辞書挿入の最悪性能 O(n2) 計算量を悪用することで引き起こされるサービス妨害 (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
の使用、 x.name
への代入、 x.name
の削除) の意味をカスタマイズすることができます。
-
object.
__getattr__
(self, name)¶ デフォルトの属性アクセスが
AttributeError
で失敗したとき (name がインスタンスの属性またはself
のクラスツリーの属性でないために__getattribute__()
がAttributeError
を送出したか、 name プロパティの__get__()
がAttributeError
を送出したとき) に呼び出されます。 このメソッドは (計算された) 属性値を返すか、AttributeError
例外を送出しなければなりません。なお、通常の過程で属性が見つかれば、
__getattr__()
は呼び出されません。(これは、__getattr__()
と__setattr__()
が意図的に非対称にされている点です。) これは、効率のためと、こうしないと__getattr__()
がインスタンスの他の属性値にアクセスする方法がなくなるためです。また、少なくともインスタンス変数に対しては、値をインスタンスの属性値辞書に挿入しないことで (代わりに他のオブジェクトに挿入することで)、属性値を完全に制御しているふりができます。実際に属性アクセスを完全に制御する方法は、以下の__getattribute__()
メソッドを参照してください。
-
object.
__getattribute__
(self, name)¶ クラスのインスタンスに対する属性アクセスを実装するために、無条件に呼び出されます。クラスが
__getattr__()
も定義している場合、__getattr__()
は、__getattribute__()
で明示的に呼び出すか、AttributeError
例外を送出しない限り呼ばれません。このメソッドは (計算された) 属性値を返すか、AttributeError
例外を送出します。このメソッドが再帰的に際限なく呼び出されてしまうのを防ぐため、実装の際には常に、必要な属性全てへのアクセスで、例えばobject.__getattribute__(self, name)
のように基底クラスのメソッドを同じ属性名を使って呼び出さなければなりません。注釈
言語構文や組み込み関数から暗黙に呼び出された特殊メソッドの検索では、このメソッドも回避されることがあります。 特殊メソッド検索 を参照してください。
object.__getattr__
にobj
とname
を渡して実行すると、 監査イベント を送出します。
-
object.
__setattr__
(self, name, value)¶ 属性の代入が試みられた際に呼び出されます。これは通常の代入の過程 (すなわち、インスタンス辞書への値の代入) の代わりに呼び出されます。name は属性名で、value はその属性に代入する値です。
__setattr__()
の中でインスタンス属性への代入が必要なら、基底クラスのこれと同じ名前のメソッドを呼び出さなければなりません。例えば、object.__setattr__(self, name, value)
とします。object.__setattr__
にobj
とname
とvalue
を渡して実行すると、 監査イベント を送出します。
-
object.
__delattr__
(self, name)¶ __setattr__()
に似ていますが、代入ではなく値の削除を行います。このメソッドを実装するのは、オブジェクトにとってdel obj.name
が意味がある場合だけにしなければなりません。object.__delattr__
にobj
とname
を渡して実行すると、 監査イベント を送出します。
-
object.
__dir__
(self)¶ オブジェクトに
dir()
が呼び出されたときに呼び出されます。シーケンスが返されなければなりません。dir()
は返されたシーケンスをリストに変換し、ソートします。
3.3.2.1. モジュールの属性値アクセスをカスタマイズする¶
特殊な名前の __getattr__
と __dir__
も、モジュール属性へのアクセスをカスタマイズするのに使えます。
モジュールレベルの __getattr__
関数は属性名である 1 引数を受け取り、計算した値を返すか AttributeError
を送出します。
属性がモジュールオブジェクトから、通常の検索、つまり object.__getattribute__()
で見付からなかった場合は、 AttributeError
を送出する前に、モジュールの __dict__
から __getattr__
が検索されます。
見付かった場合は、その属性名で呼び出され、結果が返されます。
__dir__
関数は引数を受け取らず、モジュールのアクセス可能な名前を表す文字列のシーケンスを返さなければなりません。存在する場合は、この関数はモジュールの標準の dir()
検索を上書きします。
より細かい粒度でのモジュールの動作 (属性やプロパティの設定など) のカスタマイズのために、モジュールオブジェクトの __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}...')
super().__setattr__(attr, value)
sys.modules[__name__].__class__ = VerboseModule
注釈
モジュールの __getattr__
を定義したり __class__
を設定したりしても、影響があるのは属性アクセスの構文が使われる検索だけです -- モジュールの globals への直接アクセスは (モジュール内のコードからとモジュールの globals のどちらでも) 影響を受けません。
バージョン 3.5 で変更: モジュールの属性 __class__
が書き込み可能になりました。
バージョン 3.7 で追加: __getattr__
モジュール属性と __dir__
モジュール属性。
参考
- PEP 562 - モジュールの __getattr__ と __dir__
モジュールの
__getattr__
関数および__dir__
関数の説明。
3.3.2.2. デスクリプタ (descriptor) の実装¶
以下のメソッドは、このメソッドを持つクラス (いわゆる デスクリプタ(descriptor) クラス) のインスタンスが、 オーナー (owner) クラスに存在するときにのみ適用されます (デスクリプタは、オーナーのクラス辞書か、その親のいずれかのクラス辞書になければなりません)。
以下の例では、"属性" とは、名前がオーナークラスの __dict__
のプロパティ (porperty) のキーであるような属性を指します。
-
object.
__get__
(self, instance, owner=None)¶ オーナークラス(クラス属性アクセスの場合)や、クラスのインスタンス(インスタンス属性アクセスの場合)の属性取得時に呼び出されます。 instance を通じて属性をアクセスする時に、オプションの owner 引数はオーナークラスです。 owner を通じて属性アクセスするときは
None
です。このメソッドは、算出された属性値を返すか、
AttributeError
例外を送出します。PEP 252 は
__get__()
は1つや2つの引数を持つ呼び出し可能オブジェクトであると定義しています。Pythonの組み込みのデスクリプタはこの仕様をサポートしていますが、サードパーティ製のツールの中には両方の引数を必要とするものもあります。Pythonの__getattribute__()
実装は必要かどうかに関わらず、両方の引数を常に渡します。
-
object.
__set__
(self, instance, value)¶ オーナークラスのインスタンス instance 上の属性を新たな値 value に設定する際に呼び出されます。
__set__()
あるいは__delete__()
を追加すると、デスクリプタは「データデスクリプタ」に変わります。詳細は デスクリプタの呼び出し を参照してください。
-
object.
__delete__
(self, instance)¶ オーナークラスのインスタンス instance 上の属性を削除する際に呼び出されます。
__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)
If
a
is an instance ofsuper
, then the bindingsuper(B, obj).m()
searchesobj.__class__.__mro__
for the base classA
immediately followingB
and then invokes the descriptor with the call: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__ を使うと、(プロパティのように) データメンバを明示的に宣言し、 (明示的に __slots__ で宣言しているか親クラスに存在しているかでない限り) __dict__
や __weakref__ を作成しないようにできます。
__dict__
を使うのに比べて、節約できるメモリ空間はかなり大きいです。
属性探索のスピードもかなり向上できます。
-
object.
__slots__
¶ このクラス変数には、インスタンスが用いる変数名を表す、文字列、イテラブル、または文字列のシーケンスを代入できます。__slots__ は、各インスタンスに対して宣言された変数に必要な記憶領域を確保し、
__dict__
と __weakref__ が自動的に生成されないようにします。
3.3.2.4.1. __slots__ を利用する際の注意¶
__slots__ を持たないクラスから継承するとき、インスタンスの
__dict__
属性と __weakref__ 属性は常に利用可能です。__dict__
変数がない場合、 __slots__ に列挙されていない新たな変数をインスタンスに代入することはできません。列挙されていない変数名を使って代入しようとした場合、AttributeError
が送出されます。新たな変数を動的に代入したいのなら、 __slots__ を宣言する際に'__dict__'
を変数名のシーケンスに追加してください。__slots__ を定義しているクラスの各インスタンスに __weakref__ 変数がない場合、インスタンスに対する弱参照 (
weak references
) はサポートされません。弱参照のサポートが必要なら、 __slots__ を宣言する際に'__weakref__'
を変数名のシーケンスに追加してください。__slots__ は、クラスのレベルで各変数に対する デスクリプタ を使って実装されます。その結果、 __slots__ に定義されているインスタンス変数のデフォルト値はクラス属性を使って設定できなくなっています; そうしないと、デスクリプタによる代入をクラス属性が上書きしてしまうからです。
__slots__ の宣言の作用は、それが定義されたクラスだけには留まりません。 親クラスで宣言された __slots__ は子クラスでも利用可能です。 ただし、子クラスは、自身も __slots__ (ここには 追加の スロットの名前のみ含めるべき) を定義しない限り
__dict__
や __weakref__ を持ちます。あるクラスで、基底クラスですでに定義されているスロットを定義した場合、基底クラスのスロットで定義されているインスタンス変数は (デスクリプタを基底クラスから直接取得しない限り) アクセスできなくなります。これにより、プログラムの趣意が不定になってしまいます。将来は、この問題を避けるために何らかのチェックが追加されるかもしれません。
TypeError
will be raised if nonempty __slots__ are defined for a class derived from a"variable-length" built-in type
such asint
,bytes
, andtuple
.Any non-string iterable may be assigned to __slots__.
If a
dictionary
is used to assign __slots__, the dictionary keys will be used as the slot names. The values of the dictionary can be used to provide per-attribute docstrings that will be recognised byinspect.getdoc()
and displayed in the output ofhelp()
.__class__
への代入は、両方のクラスが同じ __slots__ を持っているときのみ動作します。複数のスロットを持つ親クラスを使った 多重継承 はできますが、スロットで作成された属性を持つ親クラスは 1 つに限られます (他の基底クラスのスロットは空でなければなりません) - それに違反すると
TypeError
が送出されます。もし __slots__ に対して イテレータ を使用すると、イテレータの値ごとに デスクリプタ が作られます。しかし、 __slots__ 属性は空のイテレータとなります。
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__
のデフォルト実装は何も行いませんが、何らかの引数とともに呼び出された場合は、エラーを送出します。注釈
メタクラスのヒント
metaclass
は残りの型機構によって消費され、__init_subclass__
実装に渡されることはありません。 実際のメタクラス (明示的なヒントではなく) は、type(cls)
としてアクセスできます。バージョン 3.6 で追加.
When a class is created, type.__new__()
scans the class variables
and makes callbacks to those with a __set_name__()
hook.
-
object.
__set_name__
(self, owner, name)¶ オーナーとなるクラス owner が作成された時点で自動的に呼び出されます。 オブジェクトはそのクラスの name に割り当てられます。
class A: x = C() # Automatically calls: x.__set_name__(A, 'x')
If the class variable is assigned after the class is created,
__set_name__()
will not be called automatically. If needed,__set_name__()
can be called directly:class A: pass c = C() A.x = c # The hook is not called c.__set_name__(A, 'x') # Manually invoke the hook
詳細は クラスオブジェクトの作成 を参照してください。
バージョン 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
クラス定義の中で指定された他のキーワード引数は、後述するすべてのメタクラス操作に渡されます。
クラス定義が実行される際に、以下のステップが生じます:
MRO エントリの解決が行われる;
適切なメタクラスが決定される;
クラスの名前空間が準備される;
クラスの本体が実行される;
クラスオブジェクトが作られる。
3.3.3.2. MRO エントリの解決¶
クラス定義に現れる基底が type
のインスタンスではない場合、そのインスタンスの __mro_entries__
メソッドが検索されます。
見付かった場合、その基底そのものを要素に持つタプルを引数として、 __mro_entries__
メソッドが呼び出されます。
このメソッドは、この基底の代わりに使われるクラスのタプルを返さなければなりません。
このタプルは空であることもあり、そのような場合ではその基底は無視されます。
参考
PEP 560 - typing モジュールとジェネリック型に対する言語コアによるサポート
3.3.3.3. 適切なメタクラスの決定¶
クラス定義に対して適切なメタクラスは、以下のように決定されます:
基底も明示的なメタクラスも与えられていない場合は、
type()
が使われます;明示的なメタクラスが与えられていて、それが
type()
のインスタンス ではない 場合、それをメタクラスとして直接使います;明示的なメタクラスとして
type()
のインスタンスが与えられたか、基底が定義されていた場合は、最も派生した (継承関係で最も下の) メタクラスが使われます。
最も派生的なメタクラスは、(もしあれば) 明示的に指定されたメタクラスと、指定されたすべてのベースクラスのメタクラスから選ばれます。最も派生的なメタクラスは、これらのメタクラス候補のすべてのサブタイプであるようなものです。メタクラス候補のどれもその基準を満たさなければ、クラス定義は TypeError
で失敗します。
3.3.3.4. クラスの名前空間の準備¶
適切なメタクラスが指定されると、クラスの名前空間が用意されます。もしメタクラスが __prepare__
属性を持っている場合、 namespace = metaclass.__prepare__(name, bases, **kwds)
が呼ばれます。追加のキーワード引数は、もしクラス定義にあれば設定されます。 __prepare__
メソッドは クラスメソッド
として実装する必要があります。 __prepare__
が作成して返した名前空間は __new__
に渡されますが、最終的なクラスオブジェクトは新しい dict
にコピーして作成されます。
メタクラスに __prepare__
属性がない場合、クラスの名前空間は空の 順序付きマッピングとして初期化されます。
参考
- PEP 3115 - Metaclasses in Python 3000
__prepare__
名前空間フックの導入
3.3.3.5. クラス本体の実行¶
クラス本体が (大まかには) exec(body, globals(), namespace)
として実行されます。通常の呼び出しと exec()
の重要な違いは、クラス定義が関数内部で行われる場合、レキシカルスコープによってクラス本体 (任意のメソッドを含む) が現在のスコープと外側のスコープから名前を参照できるという点です。
しかし、クラス定義が関数内部で行われる時でさえ、クラス内部で定義されたメソッドはクラススコープで定義された名前を見ることはできません。クラス変数はインスタンスメソッドかクラスメソッドの最初のパラメータからアクセスするか、次の節で説明する、暗黙的に静的スコープが切られている __class__
参照からアクセスしなければなりません。
3.3.3.6. クラスオブジェクトの作成¶
クラス本体の実行によってクラスの名前空間が初期化されたら、metaclass(name, bases, namespace, **kwds)
を呼び出すことでクラスオブジェクトが作成されます (ここで渡される追加のキーワードは __prepare__
に渡されるものと同じです)。
このクラスオブジェクトは、 super()
の無引数形式によって参照されるものです。 __class__
は、クラス本体中のメソッドが __class__
または super
のいずれかを参照している場合に、コンパイラによって作成される暗黙のクロージャー参照です。これは、メソッドに渡された最初の引数に基づいて現在の呼び出しを行うために使用されるクラスまたはインスタンスが識別される一方、 super()
の無引数形式がレキシカルスコープに基づいて定義されているクラスを正確に識別することを可能にします。
CPython 実装の詳細: CPython 3.6 以降では、 __class__
セルは、クラス名前空間にある __classcell__
エントリーとしてメタクラスに渡されます。
__class__
セルが存在していた場合は、そのクラスが正しく初期化されるために、 type.__new__
の呼び出しに到達するまで上に伝搬されます。
失敗した場合は、Python 3.8 では RuntimeError
になります。
デフォルトのメタクラス type
や最終的には type.__new__
を呼び出すメタクラスを使っているときは、クラスオブジェクトを作成した後に次のカスタム化の手順が起動されます:
type.__new__
メソッドが__set_name__()
が定義されているクラスの名前空間にある全ての属性を収集します;それらの
__set_name__
メソッドが、そのメソッドが定義されているクラス、およびそこに属する属性に割り当てられている名前を引数として呼び出されます;新しいクラスのメソッド解決順序ですぐ上に位置する親クラスで
__init_subclass__()
フックが呼び出されます。
クラスオブジェクトが作成された後には、クラス定義に含まれているクラスデコレータ (もしあれば) にクラスオブジェクトが渡され、デコレータが返すオブジェクトがここで定義されたクラスとしてローカルの名前空間に束縛されます。
新しいクラスが type.__new__
で生成されたときは、名前空間引数として与えられたオブジェクトは新しい順序付きのマッピングに複製され、元のオブジェクトは破棄されます。
新しく複製したものは読み出し専用のプロキシでラップされ、クラスオブジェクトの __dict__
属性になります。
参考
- PEP 3135 - New super
暗黙の
__class__
クロージャ参照について記述しています
3.3.3.7. メタクラスの用途¶
メタクラスは限りない潜在的利用価値を持っています。これまで試されてきたアイデアには、列挙型、ログ記録、インターフェースのチェック、 自動デリゲーション、自動プロパティ生成、プロキシ、フレームワーク、そして自動リソースロック/同期といったものがあります。
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. ジェネリック型をエミュレートする¶
When using type annotations, it is often useful to
parameterize a generic type using Python's square-brackets notation.
For example, the annotation list[int]
might be used to signify a
list
in which all the elements are of type int
.
参考
- PEP 484 - 型ヒント
Introducing Python's framework for type annotations
- Generic Alias Types
Documentation for objects representing parameterized generic classes
- ジェネリクス, user-defined generics and
typing.Generic
実行時にパラメータ設定が可能であり、かつ静的な型チェッカーが理解できるジェネリッククラスを実装する方法のドキュメントです。
A class can generally only be parameterized if it defines the special
class method __class_getitem__()
.
-
classmethod
object.
__class_getitem__
(cls, key)¶ key にある型引数で特殊化されたジェネリッククラスを表すオブジェクトを返します。
When defined on a class,
__class_getitem__()
is automatically a class method. As such, there is no need for it to be decorated with@classmethod
when it is defined.
3.3.5.1. The purpose of __class_getitem__¶
The purpose of __class_getitem__()
is to allow runtime
parameterization of standard-library generic classes in order to more easily
apply type hints to these classes.
To implement custom generic classes that can be parameterized at runtime and
understood by static type-checkers, users should either inherit from a standard
library class that already implements __class_getitem__()
, or
inherit from typing.Generic
, which has its own implementation of
__class_getitem__()
.
Custom implementations of __class_getitem__()
on classes defined
outside of the standard library may not be understood by third-party
type-checkers such as mypy. Using __class_getitem__()
on any class for
purposes other than type hinting is discouraged.
3.3.5.2. __class_getitem__ versus __getitem__¶
Usually, the subscription of an object using square
brackets will call the __getitem__()
instance method defined on
the object's class. However, if the object being subscribed is itself a class,
the class method __class_getitem__()
may be called instead.
__class_getitem__()
should return a GenericAlias
object if it is properly defined.
Presented with the expression obj[x]
, the Python interpreter
follows something like the following process to decide whether
__getitem__()
or __class_getitem__()
should be
called:
from inspect import isclass
def subscribe(obj, x):
"""Return the result of the expression `obj[x]`"""
class_of_obj = type(obj)
# If the class of obj defines __getitem__,
# call class_of_obj.__getitem__(obj, x)
if hasattr(class_of_obj, '__getitem__'):
return class_of_obj.__getitem__(obj, x)
# Else, if obj is a class and defines __class_getitem__,
# call obj.__class_getitem__(x)
elif isclass(obj) and hasattr(obj, '__class_getitem__'):
return obj.__class_getitem__(x)
# Else, raise an exception
else:
raise TypeError(
f"'{class_of_obj.__name__}' object is not subscriptable"
)
In Python, all classes are themselves instances of other classes. The class of
a class is known as that class's metaclass, and most classes have the
type
class as their metaclass. type
does not define
__getitem__()
, meaning that expressions such as list[int]
,
dict[str, float]
and tuple[str, bytes]
all result in
__class_getitem__()
being called:
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> type(dict) == type(list) == type(tuple) == type(str) == type(bytes)
True
>>> # "list[int]" calls "list.__class_getitem__(int)"
>>> list[int]
list[int]
>>> # list.__class_getitem__ returns a GenericAlias object:
>>> type(list[int])
<class 'types.GenericAlias'>
However, if a class has a custom metaclass that defines
__getitem__()
, subscribing the class may result in different
behaviour. An example of this can be found in the enum
module:
>>> from enum import Enum
>>> class Menu(Enum):
... """A breakfast menu"""
... SPAM = 'spam'
... BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
参考
- PEP 560 - typing モジュールとジェネリック型に対する言語コアによるサポート
Introducing
__class_getitem__()
, and outlining when a subscription results in__class_getitem__()
being called instead of__getitem__()
3.3.6. 呼び出し可能オブジェクトをエミュレートする¶
-
object.
__call__
(self[, args...])¶ インスタンスが関数として "呼ばれた" 際に呼び出されます。このメソッドが定義されている場合、
x(arg1, arg2, ...)
は大まかにはtype(x).__call__(x, arg1, ...)
に変換されます。
3.3.7. コンテナをエミュレートする¶
以下に挙げるメソッドを定義することで、コンテナオブジェクトを実装できます。コンテナは通常は (リスト
や タプル
のような) シーケンス や (辞書
のような) マッピング ですが、他のコンテナも同じように表現することができます。最初のメソッド群はシーケンスもしくはマッピングを模倣するために使われます; 両者の違いは、シーケンスでキーとして使えるのは、 N をシーケンスの長さとして 0 <= k < N
を満たす整数 k 、もしくは要素の範囲を定義する slice
オブジェクトです。マッピングは、 Python の標準の 辞書
オブジェクトのメソッドと似た振る舞いをするメソッド keys()
、 values()
、 items()
、 get()
、 clear()
、 setdefault()
、 pop()
、 popitem()
、 copy()
、 update()
を提供することも推奨されています。 collections
モジュールは、 MutableMapping
抽象基底クラス を提供し、 __getitem__()
、 __setitem__()
、 __delitem__()
、 keys()
という基礎となるメソッド群から前文で挙げたメソッドを作成するのを助けてくれます。可変シーケンスは、 Python の標準の list
オブジェクトと同じように、メソッド append()
、 count()
、 index()
、 extend()
、 insert()
、 pop()
、 remove()
、 reverse()
、 sort()
を提供すべきです。最後に、シーケンス型は (連結を意味する) 加算と (繰り返しを意味する) 乗算を、以下に説明するメソッド __add__()
、 __radd__()
、 __iadd__()
、 __mul__()
、 __rmul__()
、 __imul__()
を定義して実装すべきです; そして、それ以外の数値演算子は定義すべきではありません。マッピングとシーケンスは両方とも、効率の良い in
演算子が使えるように __contains__()
メソッドを実装すべきです; マッピングでは in
はマッピングのキーを検索すべきです; シーケンスでは値を検索すべきです。マッピングもシーケンスも、コンテナの効率の良い反復処理ができるよう __iter__()
メソッドを実装すべきです; マッピングでは __iter__()
はオブジェクトのキーに対して反復処理を; シーケンスでは値全体の反復処理を行うべきです。
-
object.
__len__
(self)¶ 呼び出して組み込み関数
len()
を実装します。 オブジェクトの長さを 0 以上の整数で返さなければなりません。 また、__bool__()
メソッドを定義しておらず、__len__()
メソッドが 0 を返すようなオブジェクトは、ブール演算コンテキストでは偽とみなされます。CPython 実装の詳細: CPython では、オブジェクトの長さは最大でも
sys.maxsize
であることが要求されます。 長さがsys.maxsize
を越える場合、(len()
のような) いくつかの機能はOverflowError
を送出するでしょう。 真偽値としての判定でOverflowError
を送出しないようにするには、オブジェクトは__bool__()
メソッドを定義していなければなりません。
-
object.
__length_hint__
(self)¶ 呼び出して
operator.length_hint()
を実装します。オブジェクトの推定される長さ (実際のものより長かったり短かったりするかもしれません) を返さなければなりません。長さは 0 以上の整数でなければなりません。返り値はNotImplemented
となる場合もありますが、その場合は__length_hint__
メソッドがなかった場合と同じと扱われます。このメソッドは純粋に最適化であり、正確性は必要ではありません。バージョン 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
が送出されるものと期待しています。注釈
When subscripting a class, the special class method
__class_getitem__()
may be called instead of__getitem__()
. See __class_getitem__ versus __getitem__ for more details.
-
object.
__setitem__
(self, key, value)¶ self[key]
に対する代入を実装するために呼び出されます。__getitem__()
と同じ注意事項があてはまります。このメソッドを実装できるのは、あるキーに対する値の変更をサポートしているか、新たなキーを追加できるようなマップの場合と、ある要素を置き換えることができるシーケンスの場合だけです。不正な key に対しては、__getitem__()
メソッドと同様の例外の送出を行わなければなりません。
-
object.
__delitem__
(self, key)¶ self[key]
の削除を実装するために呼び出されます。__getitem__()
と同じ注意事項があてはまります。このメソッドを実装できるのは、キーの削除をサポートしているマップの場合と、要素を削除できるシーケンスの場合だけです。不正な key に対しては、__getitem__()
メソッドと同様の例外の送出を行わなければなりません。
-
object.
__missing__
(self, key)¶ self[key]
の実装において辞書内にキーが存在しなかった場合に、 dict のサブクラスのためにdict
.__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.8. 数値型をエミュレートする¶
以下のメソッドを定義して、数値型オブジェクトをエミュレートすることができます。特定の種類の数値型ではサポートされていないような演算に対応するメソッド (非整数の数値に対するビット単位演算など) は、未定義のままにしておかなければなりません。
-
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[, modulo])¶ -
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()
関数) は常に呼び出されます。 このメソッドがあるとその数値オブジェクトが整数型であることが示唆されます。 整数を返さなければなりません。もし
__int__()
,__float__()
,__complex__()
が定義されていない場合、組み込み関数のint()
,float()
,complex()
は__index__()
にフォールバックします。
-
object.
__round__
(self[, ndigits])¶ -
object.
__trunc__
(self)¶ -
object.
__floor__
(self)¶ -
object.
__ceil__
(self)¶ 組み込み関数の
round()
とmath
モジュール関数のtrunc()
,floor()
,ceil()
の実装から呼び出されます。 ndigits が__round__()
に渡されない限りは、これらの全てのメソッドはIntegral
(たいていはint
) に切り詰められたオブジェクトの値を返すべきです。The built-in function
int()
falls back to__trunc__()
if neither__int__()
nor__index__()
is defined.
3.3.9. with文とコンテキストマネージャ¶
コンテキストマネージャ(context manager) とは、 with
文の実行時にランタイムコンテキストを定義するオブジェクトです。コンテキストマネージャは、コードブロックを実行するために必要な入り口および出口の処理を扱います。コンテキストマネージャは通常、 with
文( with 文 の章を参照)により起動されますが、これらのメソッドを直接呼び出すことで起動することもできます。
コンテキストマネージャの代表的な使い方としては、様々なグローバル情報の保存および更新、リソースのロックとアンロック、ファイルのオープンとクローズなどが挙げられます。
コンテキストマネージャについてのさらなる情報については、 コンテキストマネージャ型 を参照してください。
-
object.
__exit__
(self, exc_type, exc_value, traceback)¶ コンテキストマネージャの出口で実行される処理です。パラメータは、コンテキストが終了した原因となった例外について説明しています。コンテキストが例外を送出せず終了した場合は、全ての引き数に
None
が設定されます。もし、例外が送出され、かつメソッドが例外を抑制したい場合(すなわち、例外が伝播されるのを防ぎたい場合)、このメソッドは True を返す必要があります。そうでなければ、このメソッドの終了後、例外は通常通り伝播することになります。
__exit__()
メソッドは受け取った例外を再度送出すべきではありません。これは、呼び出し側の責任でおこなってください。
3.3.10. クラスパターンマッチの位置引数のカスタマイズ¶
パターンの中でクラス名を利用する場合、位置引数はデフォルトでは利用できません。 MyClass
で特別なサポートがないと、 case MyClass(x, y)
は通常無効です。このようなパターンを利用するには、 __match_args__ 属性をクラスに定義する必要があります。
-
object.
__match_args__
¶ このクラス変数には文字列のタプルがアサイン可能です。このクラスがクラスパターンの位置引数の中で利用されると、それぞれの位置引数は対応する __match_args__ の中の値をキーワードとする、キーワード引数に変換されます。この属性がない時は、
()
が設定されているのと同義です。
例えば、もし MyClass.__match_args__
に ("left", "center", "right")
が定義されていた場合、 case MyClass(x, y)
は case MyClass(left=x, center=y)
と同義です。パターンの引数の数は、 __match_args__ の要素数と同等かそれ以下でなければならない点に注意してください。もし、多かった場合には、パターンマッチは TypeError
を送出します。
バージョン 3.10 で追加.
参考
- PEP 634 - 構造的パターンマッチ
match
文の詳細。
3.3.11. 特殊メソッド検索¶
カスタムクラスでは、特殊メソッドの暗黙の呼び出しは、オブジェクトのインスタンス辞書ではなく、オブジェクトの型で定義されているときにのみ正しく動作することが保証されます。この動作のため、以下のコードは例外を送出します:
>>> 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オブジェクト は待機可能です。
注釈
The generator iterator objects returned from generators
decorated with types.coroutine()
or asyncio.coroutine()
are also awaitable, but they do not implement __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
(value)¶ -
coroutine.
throw
(type[, value[, traceback]]) コルーチンで指定された例外を送出します。 このメソッドは、イテレータにコルーチンを一時停止する
throw()
メソッドがある場合に処理を委任します。 そうでない場合には、中断した地点から例外が送出されます。 結果 (返り値かStopIteration
かその他の例外) は、上で解説したような__await__()
の返り値に対して反復処理を行ったときと同じです。 例外がコルーチンの中で捕捉されなかった場合、呼び出し元へ伝搬されます。
-
coroutine.
close
()¶ コルーチンが自分自身の後片付けをし終了します。 コルーチンが一時停止している場合は、コルーチンを一時停止させたイテレータに
close()
メソッドがあれば、まずはそれに処理を委任します。 そして一時停止した地点からGeneratorExit
が送出され、ただちにコルーチンが自分自身の後片付けを行います。 最後に、実行が開始されていなかった場合でも、コルーチンに実行が完了した印を付けます。コルーチンオブジェクトが破棄されるときには、上記の手順を経て自動的に閉じられます。
3.4.3. 非同期イテレータ (Asynchronous Iterator)¶
非同期イテレータ の __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.7 で変更: Python 3.7 より前では、 __aiter__()
は 非同期イテレータ になる awaitable を返せました。
Python 3.7 からは、 __aiter__()
は非同期イテレータオブジェクトを返さなければなりません。
それ以外のものを返すと TypeError
になります。
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__()
) が失敗した場合、その演算はサポートされていないとみなされます。これは、反射したメソッドが呼び出されない理由です。