3. データモデル—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.8/reference/datamodel
移動先:案内検索

3.3。 データ・モデル

3.1。 オブジェクト、値、およびタイプ

オブジェクトは、Pythonによるデータの抽象化です。 Pythonプログラムのすべてのデータは、オブジェクトまたはオブジェクト間の関係によって表されます。 (ある意味で、フォンノイマンの「ストアドプログラムコンピュータ」のモデルに準拠して、コードもオブジェクトによって表されます。)

すべてのオブジェクトには、ID、タイプ、および値があります。 オブジェクトの identity は、一度作成されると変更されることはありません。 あなたはそれをメモリ内のオブジェクトのアドレスと考えるかもしれません。 ' is '演算子は、2つのオブジェクトのIDを比較します。 id()関数は、そのIDを表す整数を返します。

オブジェクトのタイプは、オブジェクトがサポートする操作(たとえば、「長さはありますか?」)を決定し、そのタイプのオブジェクトの可能な値も定義します。 type()関数は、オブジェクトの型(オブジェクト自体)を返します。 そのアイデンティティと同様に、オブジェクトのタイプも変更できません。 1

一部のオブジェクトのは変更される可能性があります。 値が変更される可能性のあるオブジェクトは、可変と呼ばれます。 作成後に値が変更できないオブジェクトは、 immutable と呼ばれます。 (可変オブジェクトへの参照を含む不変コンテナオブジェクトの値は、後者の値が変更されると変更される可能性がありますが、コンテナに含まれるオブジェクトのコレクションは変更できないため、コンテナは引き続き不変と見なされます。 したがって、不変性は、変更できない値を持つことと厳密には同じではなく、より微妙です。)オブジェクトの可変性は、そのタイプによって決定されます。 たとえば、数字、文字列、タプルは不変ですが、辞書とリストは変更可能です。

オブジェクトが明示的に破棄されることはありません。 ただし、到達不能になると、ガベージコレクションされる可能性があります。 実装では、ガベージコレクションを延期したり、完全に省略したりできます。まだ到達可能なオブジェクトが収集されない限り、ガベージコレクションの実装方法は実装品質の問題です。

実装のトレースまたはデバッグ機能を使用すると、通常は収集可能なオブジェクトが存続する可能性があることに注意してください。 また、「 tryexcept 」ステートメントで例外をキャッチすると、オブジェクトが存続する可能性があることに注意してください。

一部のオブジェクトには、開いているファイルやウィンドウなどの「外部」リソースへの参照が含まれています。 これらのリソースは、オブジェクトがガベージコレクションされるときに解放されることが理解されますが、ガベージコレクションが発生することが保証されていないため、このようなオブジェクトは、外部リソースを解放する明示的な方法(通常はclose()メソッド)も提供します。 このようなオブジェクトを明示的に閉じるプログラムを強くお勧めします。 ' tryfinally 'ステートメントと ' with 'ステートメントは、これを行うための便利な方法を提供します。

一部のオブジェクトには、他のオブジェクトへの参照が含まれています。 これらはコンテナと呼ばれます。 コンテナーの例は、タプル、リスト、および辞書です。 参照はコンテナの値の一部です。 ほとんどの場合、コンテナの値について話すときは、含まれているオブジェクトのIDではなく、値を意味します。 ただし、コンテナの可変性について説明する場合、すぐに含まれるオブジェクトのIDのみが暗示されます。 したがって、不変のコンテナ(タプルなど)に可変オブジェクトへの参照が含まれている場合、その可変オブジェクトが変更されると、その値が変更されます。

タイプは、オブジェクトの動作のほぼすべての側面に影響します。 オブジェクトIDの重要性でさえ、ある意味で影響を受けます。不変型の場合、新しい値を計算する操作は、実際には同じ型と値を持つ既存のオブジェクトへの参照を返す可能性がありますが、可変オブジェクトの場合は許可されません。 たとえば、a = 1; b = 1の後、abは、実装に応じて、値が1の同じオブジェクトを参照する場合としない場合がありますが、c = []; d = []の後です。 、cおよびdは、新しく作成された2つの異なる一意の空のリストを参照することが保証されています。 (c = d = []cdの両方に同じオブジェクトを割り当てることに注意してください。)


3.2。 標準タイプ階層

以下は、Pythonに組み込まれているタイプのリストです。 拡張モジュール(実装に応じて、C、Java、またはその他の言語で記述されている)は、追加の型を定義できます。 Pythonの将来のバージョンでは、型階層に型が追加される可能性があります(たとえば、有理数、効率的に格納された整数の配列など)。ただし、そのような追加は、代わりに標準ライブラリを介して提供されることがよくあります。

以下のタイプの説明の一部には、「特別な属性」をリストした段落が含まれています。 これらは、実装へのアクセスを提供する属性であり、一般的な使用を目的としたものではありません。 それらの定義は将来変更される可能性があります。

なし

このタイプには単一の値があります。 この値を持つ単一のオブジェクトがあります。 このオブジェクトには、組み込み名Noneを介してアクセスします。 これは、多くの状況で値がないことを示すために使用されます。たとえば、明示的に何も返さない関数から返されます。 その真理値は偽です。

実装されていません

このタイプには単一の値があります。 この値を持つ単一のオブジェクトがあります。 このオブジェクトには、組み込み名NotImplementedを介してアクセスします。 数値メソッドと豊富な比較メソッドは、提供されたオペランドの演算を実装していない場合、この値を返す必要があります。 (その後、インタプリタは、演算子に応じて、反映された操作またはその他のフォールバックを試行します。)その真理値はtrueです。

詳細については、算術演算の実装を参照してください。

省略記号

このタイプには単一の値があります。 この値を持つ単一のオブジェクトがあります。 このオブジェクトには、リテラル...または組み込み名Ellipsisを介してアクセスします。 その真理値は真です。

numbers.Number

これらは数値リテラルによって作成され、算術演算子および算術組み込み関数によって結果として返されます。 数値オブジェクトは不変です。 一度作成すると、その値は変更されません。 Pythonの数値はもちろん数学の数値と強く関連していますが、コンピューターでの数値表現の制限があります。

__repr__()および__str__()によって計算される数値クラスの文字列表現には、次のプロパティがあります。

  • これらは有効な数値リテラルであり、クラスコンストラクターに渡されると、元の数値の値を持つオブジェクトを生成します。

  • 可能な場合、表現は10進数になります。

  • 小数点の前の単一のゼロを除いて、先行ゼロは表示されません。

  • 小数点以下の単一のゼロを除いて、後続のゼロは表示されません。

  • 符号は、数値が負の場合にのみ表示されます。

Pythonは、整数、浮動小数点数、および複素数を区別します。

numbers.Integral

これらは、整数の数学的セット(正と負)の要素を表します。

整数には次の2つのタイプがあります。

整数( int

これらは、使用可能な(仮想)メモリのみを条件として、無制限の範囲の数値を表します。 シフトおよびマスク操作の目的で、2進表現が想定され、負の数は2の補数の変形で表され、左に伸びる無限の符号ビットの文字列のような錯覚を与えます。

ブール値( bool

これらは、真理値FalseおよびTrueを表します。 値FalseTrueを表す2つのオブジェクトは、唯一のブールオブジェクトです。 ブール型は整数型のサブタイプであり、ブール値は、文字列に変換されるときに文字列"False"または"True"がそれぞれ返されます。

整数表現の規則は、負の整数を含むシフトおよびマスク演算の最も意味のある解釈を提供することを目的としています。

numbers.Realfloat

これらは、マシンレベルの倍精度浮動小数点数を表します。 許容範囲とオーバーフローの処理については、基盤となるマシンアーキテクチャ(およびCまたはJavaの実装)に翻弄されます。 Pythonは単精度浮動小数点数をサポートしていません。 通常これらを使用する理由であるプロセッサとメモリの使用量の節約は、Pythonでオブジェクトを使用するオーバーヘッドによって小さくなります。したがって、2種類の浮動小数点数で言語を複雑にする理由はありません。

numbers.Complexcomplex

これらは、複素数をマシンレベルの倍精度浮動小数点数のペアとして表します。 浮動小数点数の場合と同じ警告が適用されます。 複素数zの実数部と虚数部は、読み取り専用属性z.realおよびz.imagを介して取得できます。

シーケンス

これらは、非負の数でインデックス付けされた有限順序集合を表します。 組み込み関数 len()は、シーケンスの項目数を返します。 シーケンスの長さが n の場合、インデックスセットには0、1、…、 n -1の番号が含まれます。 シーケンス a のアイテム ia[i]によって選択されます。

シーケンスはスライスもサポートします。a[i:j]は、 i <= k <のように、インデックス k を持つすべてのアイテムを選択します。 ] j 。 式として使用する場合、スライスは同じタイプのシーケンスです。 これは、インデックスセットの番号が0から始まるように再番号付けされることを意味します。

一部のシーケンスは、3番目の「ステップ」パラメーターを使用した「拡張スライス」もサポートしています。a[i:j:k]は、インデックス xa のすべてのアイテムを選択します。 n >= 0および i <= x < j

シーケンスは、その可変性によって区別されます。

不変のシーケンス

不変のシーケンスタイプのオブジェクトは、一度作成されると変更できません。 (オブジェクトに他のオブジェクトへの参照が含まれている場合、これらの他のオブジェクトは変更可能であり、変更される可能性があります。ただし、不変オブジェクトによって直接参照されるオブジェクトのコレクションは変更できません。)

次のタイプは不変のシーケンスです。

文字列

文字列は、Unicodeコードポイントを表す一連の値です。 U+0000 - U+10FFFFの範囲内のすべてのコードポイントを文字列で表すことができます。 Pythonには char タイプはありません。 代わりに、文字列内のすべてのコードポイントは、長さが1の文字列オブジェクトとして表されます。 組み込み関数 ord()は、コードポイントを文字列形式から0 - 10FFFFの範囲の整数に変換します。 chr()は、0 - 10FFFFの範囲の整数を対応する長さ1の文字列オブジェクトに変換します。 str.encode()は、指定されたテキストエンコーディングと bytes.decode()を使用して、 strbytes に変換するために使用できます。反対を達成するために使用することができます。

タプル

タプルの項目は任意のPythonオブジェクトです。 2つ以上の項目のタプルは、コンマで区切られた式のリストによって形成されます。 1つの項目のタプル(「シングルトン」)は、式にコンマを付加することで形成できます(式のグループ化には括弧を使用できる必要があるため、式自体ではタプルは作成されません)。 空のタプルは、空の括弧のペアによって形成できます。

バイト

バイトオブジェクトは不変の配列です。 項目は8ビットバイトで、0 <= x <256の範囲の整数で表されます。 バイトリテラル(b'abc'など)および組み込みの bytes()コンストラクターを使用して、バイトオブジェクトを作成できます。 また、バイトオブジェクトは decode()メソッドを介して文字列にデコードできます。

可変シーケンス

可変シーケンスは、作成後に変更できます。 サブスクリプションおよびスライス表記は、割り当ておよび del (削除)ステートメントのターゲットとして使用できます。

現在、2つの固有の可変シーケンスタイプがあります。

リスト

リストの項目は任意のPythonオブジェクトです。 リストは、コンマで区切られた式のリストを角括弧で囲むことによって形成されます。 (長さ0または1のリストを作成するために特別な場合は必要ないことに注意してください。)

バイト配列

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

拡張モジュール array は、 collections モジュールと同様に、可変シーケンスタイプの追加の例を提供します。

タイプを設定する

これらは、一意の不変オブジェクトの順序付けられていない有限のセットを表します。 そのため、添え字でインデックスを付けることはできません。 ただし、それらは繰り返すことができ、組み込み関数 len()はセット内のアイテムの数を返します。 セットの一般的な用途は、高速メンバーシップテスト、シーケンスからの重複の削除、交差、和集合、差、対称差などの数学演算の計算です。

セット要素の場合、辞書キーの場合と同じ不変性ルールが適用されます。 数値型は、数値比較の通常の規則に従うことに注意してください。2つの数値が等しい場合(たとえば、11.0)、セットに含めることができるのは1つだけです。

現在、2つの固有のセットタイプがあります。

セット

これらは可変セットを表します。 これらは、組み込みの set()コンストラクターによって作成され、add()などのいくつかのメソッドによって後で変更できます。

冷凍セット

これらは不変のセットを表します。 これらは、組み込みの floatset()コンストラクターによって作成されます。 フリーズセットは不変でハッシュ可能であるため、別のセットの要素として、または辞書キーとして再び使用できます。

マッピング

これらは、任意のインデックスセットによってインデックス付けされたオブジェクトの有限セットを表します。 添え字表記a[k]は、マッピングaからkでインデックス付けされたアイテムを選択します。 これは、式で使用したり、割り当てまたは del ステートメントのターゲットとして使用したりできます。 組み込み関数 len()は、マッピング内のアイテムの数を返します。

現在、単一の固有のマッピングタイプがあります。

辞書

これらは、ほぼ任意の値でインデックス付けされたオブジェクトの有限セットを表します。 キーとして受け入れられない値のタイプは、リストや辞書を含む値、またはオブジェクトIDではなく値によって比較されるその他の可変タイプのみです。これは、辞書を効率的に実装するには、キーのハッシュ値を一定に保つ必要があるためです。 キーに使用される数値タイプは、数値比較の通常の規則に従います。2つの数値が等しい場合(たとえば、11.0)、同じ辞書エントリにインデックスを付けるために交換可能に使用できます。

ディクショナリは挿入順序を保持します。つまり、キーはディクショナリ上で順番に追加されたのと同じ順序で生成されます。 既存のキーを置き換えても順序は変わりませんが、キーを削除して再度挿入すると、古い場所を維持するのではなく、最後に追加されます。

辞書は変更可能です。 これらは、{...}表記で作成できます(セクション辞書表示を参照)。

拡張モジュール dbm.ndbm および dbm.gnu は、 collections モジュールと同様に、マッピングタイプの追加の例を提供します。

バージョン3.7で変更:辞書は、3.6より前のバージョンのPythonで挿入順序を保持しませんでした。 CPython 3.6では、挿入順序は保持されていましたが、言語の保証ではなく、当時は実装の詳細と見なされていました。

呼び出し可能なタイプ

関数呼び出し操作(セクション呼び出しを参照)を適用できるタイプは次のとおりです。

ユーザー定義関数

ユーザー定義関数オブジェクトは、関数定義によって作成されます(セクション関数定義を参照)。 関数の仮パラメータリストと同じ数の項目を含む引数リストを使用して呼び出す必要があります。

特別な属性:

属性

意味

__doc__

関数のドキュメント文字列、または使用できない場合はNone。 サブクラスには継承されません。

書き込み可能

__name__

関数の名前。

書き込み可能

__qualname__

関数の修飾名

バージョン3.3の新機能。

書き込み可能

__module__

関数が定義されたモジュールの名前、または使用できない場合はNone

書き込み可能

__defaults__

デフォルトを持つ引数のデフォルト引数値を含むタプル、またはデフォルト値を持つ引数がない場合はNone

書き込み可能

__code__

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

書き込み可能

__globals__

関数のグローバル変数(関数が定義されたモジュールのグローバル名前空間)を保持するディクショナリへの参照。

読み取り専用

__dict__

任意の関数属性をサポートする名前空間。

書き込み可能

__closure__

Noneまたは関数の自由変数のバインディングを含むセルのタプル。 cell_contents属性については、以下を参照してください。

読み取り専用

__annotations__

パラメータの注釈を含むdict。 dictのキーはパラメーター名であり、提供されている場合は、returnアノテーションの'return'です。

書き込み可能

__kwdefaults__

キーワードのみのパラメータのデフォルトを含むdict。

書き込み可能

「書き込み可能」というラベルの付いた属性のほとんどは、割り当てられた値のタイプをチェックします。

関数オブジェクトは、任意の属性の取得と設定もサポートします。これは、たとえば、メタデータを関数に添付するために使用できます。 通常の属性ドット表記は、そのような属性を取得および設定するために使用されます。 現在の実装では、ユーザー定義関数の関数属性のみがサポートされていることに注意してください。 組み込み関数の関数属性は、将来サポートされる可能性があります。

セルオブジェクトの属性はcell_contentsです。 これを使用して、セルの値を取得したり、値を設定したりできます。

関数の定義に関する追加情報は、そのコードオブジェクトから取得できます。 以下の内部タイプの説明を参照してください。 セルタイプは、タイプモジュールでアクセスできます。

インスタンスメソッド

インスタンスメソッドオブジェクトは、クラス、クラスインスタンス、および呼び出し可能なオブジェクト(通常はユーザー定義関数)を組み合わせたものです。

特別な読み取り専用属性:__self__はクラスインスタンスオブジェクト、__func__は関数オブジェクトです。 __doc__はメソッドのドキュメントです(__func__.__doc__と同じ)。 __ name __ はメソッド名です(__func__.__name__と同じ)。 __module__は、メソッドが定義されたモジュールの名前です。使用できない場合は、Noneです。

メソッドは、基になる関数オブジェクトの任意の関数属性へのアクセス(設定ではない)もサポートします。

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

インスタンスの1つを介してクラスからユーザー定義関数オブジェクトを取得することによってインスタンスメソッドオブジェクトが作成される場合、その__self__属性はインスタンスであり、メソッドオブジェクトはバインドされていると言われます。 新しいメソッドの__func__属性は、元の関数オブジェクトです。

クラスまたはインスタンスからクラスメソッドオブジェクトを取得してインスタンスメソッドオブジェクトを作成する場合、その__self__属性はクラス自体であり、その__func__属性はクラスメソッドの基礎となる関数オブジェクトです。

インスタンスメソッドオブジェクトが呼び出されると、基になる関数(__func__)が呼び出され、引数リストの前にクラスインスタンス(__self__)が挿入されます。 たとえば、Cが関数f()の定義を含むクラスであり、xCのインスタンスである場合、 [を呼び出します。 X149X]は、C.f(x, 1)を呼び出すのと同じです。

インスタンスメソッドオブジェクトがクラスメソッドオブジェクトから派生している場合、__self__に格納されている「クラスインスタンス」は実際にはクラス自体であるため、x.f(1)またはC.f(1)のいずれかを呼び出します。 f(C,1)を呼び出すのと同じです。ここで、fは基礎となる関数です。

関数オブジェクトからインスタンスメソッドオブジェクトへの変換は、属性がインスタンスから取得されるたびに発生することに注意してください。 場合によっては、有益な最適化は、属性をローカル変数に割り当て、そのローカル変数を呼び出すことです。 また、この変換はユーザー定義関数に対してのみ発生することに注意してください。 他の呼び出し可能オブジェクト(および呼び出し不可能なすべてのオブジェクト)は、変換せずに取得されます。 クラスインスタンスの属性であるユーザー定義関数は、バインドされたメソッドに変換されないことに注意することも重要です。 こののみは、関数がクラスの属性である場合に発生します。

ジェネレーター機能

yield ステートメント(セクション yieldステートメントを参照)を使用する関数またはメソッドは、ジェネレーター関数と呼ばれます。 このような関数は、呼び出されると、関数の本体を実行するために使用できるイテレータオブジェクトを常に返します。イテレータの iterator .__ next __()メソッドを呼び出すと、値が提供されるまで関数が実行されます。 yieldステートメントを使用します。 関数が return ステートメントを実行するか、最後から外れると、 StopIteration 例外が発生し、イテレーターは返される値のセットの最後に到達します。

コルーチン機能

async def を使用して定義された関数またはメソッドは、コルーチン関数と呼ばれます。 このような関数は、呼び出されると、コルーチンオブジェクトを返します。 await 式、 async with および async for ステートメントが含まれる場合があります。 コルーチンオブジェクトセクションも参照してください。

非同期発電機機能

async def を使用して定義され、 yield ステートメントを使用する関数またはメソッドは、非同期ジェネレーター関数と呼ばれます。 このような関数は、呼び出されると、 async for ステートメントで使用して関数の本体を実行できる非同期イテレーターオブジェクトを返します。

非同期イテレータのaiterator.__anext__()メソッドを呼び出すと、 awaitable が返されます。このメソッドは、待機すると、 yield 式を使用して値を提供するまで実行されます。 関数が空の return ステートメントを実行するか、最後から外れると、 StopAsyncIteration 例外が発生し、非同期イテレーターは、生成される値のセットの最後に到達します。

組み込み関数

組み込み関数オブジェクトは、C関数のラッパーです。 組み込み関数の例は、 len()および math.sin()です( math は標準の組み込みモジュールです)。 引数の数とタイプは、C関数によって決定されます。 特別な読み取り専用属性:__doc__は関数のドキュメント文字列、または使用できない場合はNoneです。 __ name __ は関数の名前です。 __self__Noneに設定されています(ただし、次の項目を参照してください)。 __module__は、関数が定義されたモジュールの名前です。使用できない場合は、Noneです。

組み込みメソッド

これは実際には組み込み関数の別の偽装であり、今回は暗黙の追加引数としてC関数に渡されたオブジェクトが含まれています。 組み込みメソッドの例は、 alist がリストオブジェクトであると仮定した場合のalist.append()です。 この場合、特別な読み取り専用属性__self__は、 alist で示されるオブジェクトに設定されます。

クラス

クラスは呼び出し可能です。 これらのオブジェクトは通常、それ自体の新しいインスタンスのファクトリとして機能しますが、__new__()をオーバーライドするクラスタイプのバリエーションが可能です。 呼び出しの引数は__new__()に渡され、通常は__init__()に渡されて新しいインスタンスが初期化されます。

クラスインスタンス

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

モジュール

モジュールはPythonコードの基本的な組織単位であり、 import ステートメントによって、または importlib.import_module(などの関数を呼び出すことによって呼び出される import system によって作成されます。 )および組み込み __ import __()。 モジュールオブジェクトには、ディクショナリオブジェクトによって実装された名前空間があります(これは、モジュールで定義された関数の__globals__属性によって参照されるディクショナリです)。 属性参照は、このディクショナリのルックアップに変換されます。たとえば、m.xm.__dict__["x"]と同等です。 モジュールオブジェクトには、モジュールの初期化に使用されるコードオブジェクトが含まれていません(初期化が完了すると必要ないため)。

属性の割り当てにより、モジュールの名前空間ディクショナリが更新されます。たとえば、m.x = 1m.__dict__["x"] = 1と同等です。

事前定義された(書き込み可能な)属性: __ name __ はモジュールの名前です。 __doc__はモジュールのドキュメント文字列であり、使用できない場合はNoneです。 __annotations__(オプション)は、モジュール本体の実行中に収集された変数注釈を含む辞書です。 __ file __ は、モジュールがファイルからロードされた場合、モジュールがロードされたファイルのパス名です。 __ file __ 属性は、インタープリターに静的にリンクされているCモジュールなど、特定のタイプのモジュールでは欠落している可能性があります。 共有ライブラリから動的にロードされる拡張モジュールの場合、これは共有ライブラリファイルのパス名です。

特別な読み取り専用属性: __ dict __ は、辞書オブジェクトとしてのモジュールの名前空間です。

カスタムクラス

カスタムクラスタイプは通常、クラス定義によって作成されます(セクションクラス定義を参照)。 クラスには、辞書オブジェクトによって実装された名前空間があります。 クラス属性参照は、このディクショナリのルックアップに変換されます。たとえば、C.xC.__dict__["x"]に変換されます(ただし、属性を見つける他の手段を可能にするフックがいくつかあります)。 そこに属性名が見つからない場合は、基本クラスで属性検索が続行されます。 この基本クラスの検索では、共通の祖先に戻る複数の継承パスが存在する「ダイヤモンド」継承構造が存在する場合でも正しく動作するC3メソッドの解決順序が使用されます。 Pythonで使用されるC3MROの詳細については、2.3リリースに付属のドキュメント https://www.python.org/download/releases/2.3/mro/を参照してください。

クラス属性参照(たとえば、クラスCの場合)がクラスメソッドオブジェクトを生成する場合、__self__属性がCであるインスタンスメソッドオブジェクトに変換されます。 静的メソッドオブジェクトを生成する場合、静的メソッドオブジェクトによってラップされたオブジェクトに変換されます。 クラスから取得された属性がその __ dict __ に実際に含まれている属性と異なる可能性がある別の方法については、セクション記述子の実装を参照してください。

クラス属性の割り当てにより、クラスのディクショナリが更新されますが、基本クラスのディクショナリは更新されません。

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

特別な属性: __ name __ はクラス名です。 __module__は、クラスが定義されたモジュール名です。 __ dict __ は、クラスの名前空間を含む辞書です。 __ bases __ は、基本クラスリストに出現する順序で基本クラスを含むタプルです。 __doc__はクラスのドキュメント文字列、または未定義の場合はNoneです。 __annotations__(オプション)は、クラス本体の実行中に収集された変数アノテーションを含む辞書です。

クラスインスタンス

クラスインスタンスは、クラスオブジェクトを呼び出すことによって作成されます(上記を参照)。 クラスインスタンスには、属性参照が検索される最初の場所である辞書として実装された名前空間があります。 そこに属性が見つからず、インスタンスのクラスにその名前の属性がある場合、検索はクラス属性で続行されます。 ユーザー定義の関数オブジェクトであるクラス属性が見つかった場合、それは__self__属性がインスタンスであるインスタンスメソッドオブジェクトに変換されます。 静的メソッドおよびクラスメソッドオブジェクトも変換されます。 上記の「クラス」を参照してください。 インスタンスを介して取得されたクラスの属性が、クラスの __ dict __ に実際に格納されているオブジェクトと異なる可能性がある別の方法については、セクション記述子の実装を参照してください。 クラス属性が見つからず、オブジェクトのクラスに__getattr__()メソッドがある場合、ルックアップを満たすために呼び出されます。

属性の割り当てと削除により、インスタンスのディクショナリが更新されますが、クラスのディクショナリは更新されません。 クラスに__setattr__()または__delattr__()メソッドがある場合、インスタンスディクショナリを直接更新する代わりに、これが呼び出されます。

クラスインスタンスは、特定の特別な名前のメソッドがある場合、数値、シーケンス、またはマッピングのふりをすることができます。 セクション特別なメソッド名を参照してください。

特別な属性: __ dict __ は属性辞書です。 __ class __ はインスタンスのクラスです。

I / Oオブジェクト(ファイルオブジェクトとも呼ばれます)

ファイルオブジェクトは開いているファイルを表します。 ファイルオブジェクトを作成するには、さまざまなショートカットを使用できます。 open()組み込み関数、 os.popen()os.fdopen()、およびソケットオブジェクトの makefile()メソッド(およびおそらく拡張モジュールによって提供される他の関数またはメソッドによる)。

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

内部タイプ

インタプリタによって内部的に使用されるいくつかのタイプは、ユーザーに公開されます。 それらの定義は、インタープリターの将来のバージョンで変更される可能性がありますが、完全を期すためにここで説明します。

コードオブジェクト

コードオブジェクトは、バイトコンパイルされた実行可能Pythonコード、またはバイトコードを表します。 コードオブジェクトと関数オブジェクトの違いは、関数オブジェクトには関数のグローバル(それが定義されたモジュール)への明示的な参照が含まれているのに対し、コードオブジェクトにはコンテキストが含まれていないことです。 また、デフォルトの引数値は、コードオブジェクトではなく、関数オブジェクトに格納されます(実行時に計算された値を表すため)。 関数オブジェクトとは異なり、コードオブジェクトは不変であり、可変オブジェクトへの参照(直接的または間接的)は含まれていません。

特別な読み取り専用属性:co_nameは関数名を示します。 co_argcountは、位置引数(位置のみの引数とデフォルト値の引数を含む)の総数です。 co_posonlyargcountは、位置のみの引数(デフォルト値の引数を含む)の数です。 co_kwonlyargcountは、キーワードのみの引数(デフォルト値の引数を含む)の数です。 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には次のフラグビットが定義されています。関数が*arguments構文を使用して任意の数の位置引数を受け入れる場合、ビット0x04が設定されます。 関数が**keywords構文を使用して任意のキーワード引数を受け入れる場合、ビット0x08が設定されます。 関数がジェネレータの場合、ビット0x20が設定されます。

将来の機能宣言(from __future__ import division)でも、co_flagsのビットを使用して、コードオブジェクトが特定の機能を有効にしてコンパイルされたかどうかを示します。関数がでコンパイルされた場合、ビット0x2000が設定されます。将来の分割が可能になりました。 ビット0x10および0x1000は、以前のバージョンのPythonで使用されていました。

co_flagsの他のビットは、内部使用のために予約されています。

コードオブジェクトが関数を表す場合、co_constsの最初の項目は関数のドキュメント文字列、または未定義の場合はNoneです。

フレームオブジェクト

フレームオブジェクトは実行フレームを表します。 これらはトレースバックオブジェクトで発生する可能性があり(以下を参照)、登録されたトレース関数にも渡されます。

特別な読み取り専用属性:f_backは前のスタックフレーム(呼び出し元に向かって)、またはこれが一番下のスタックフレームの場合はNoneです。 f_codeは、このフレームで実行されているコードオブジェクトです。 f_localsは、ローカル変数を検索するために使用される辞書です。 f_globalsはグローバル変数に使用されます。 f_builtinsは、組み込み(固有)名に使用されます。 f_lastiは正確な指示を与えます(これはコードオブジェクトのバイトコード文字列へのインデックスです)。

f_codeにアクセスすると、監査イベント object.__getattr__が引数objおよび"f_code"で発生します。

特別な書き込み可能な属性:f_traceは、Noneでない場合、コード実行中にさまざまなイベントに対して呼び出される関数です(これはデバッガーによって使用されます)。 通常、イベントは新しいソース行ごとにトリガーされます。これは、f_trace_linesFalse に設定することで無効にできます。

実装 may では、f_trace_opcodesTrue に設定することにより、オペコードごとのイベントを要求できます。 trace関数によって発生した例外がトレースされている関数にエスケープされると、これによりインタプリタの動作が未定義になる可能性があることに注意してください。

f_linenoは、フレームの現在の行番号です。トレース関数内からこれに書き込むと、指定された行にジャンプします(最下部のフレームのみ)。 デバッガーは、f_linenoに書き込むことにより、Jumpコマンド(別名Set Next Statement)を実装できます。

フレームオブジェクトは次の1つの方法をサポートします。

frame.clear()

このメソッドは、フレームによって保持されているローカル変数へのすべての参照をクリアします。 また、フレームがジェネレーターに属している場合、ジェネレーターはファイナライズされます。 これは、フレームオブジェクトに関連する参照サイクルを中断するのに役立ちます(たとえば、例外をキャッチし、後で使用するためにそのトレースバックを保存する場合)。

フレームが現在実行中の場合、 RuntimeError が発生します。

バージョン3.4の新機能。

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

トレースバックオブジェクトは、例外のスタックトレースを表します。 トレースバックオブジェクトは、例外が発生したときに暗黙的に作成されます。また、 types.TracebackType を呼び出すことによって明示的に作成することもできます。

暗黙的に作成されたトレースバックの場合、例外ハンドラーの検索によって実行スタックが巻き戻されると、巻き戻された各レベルで、現在のトレースバックの前にトレースバックオブジェクトが挿入されます。 例外ハンドラーが入力されると、スタックトレースがプログラムで使用できるようになります。 (セクション tryステートメントを参照してください。)sys.exc_info()によって返されるタプルの3番目の項目として、およびキャッチされた例外の__traceback__属性としてアクセスできます。

プログラムに適切なハンドラーが含まれていない場合、スタックトレースは標準エラーストリームに書き込まれます(適切にフォーマットされます)。 インタプリタがインタラクティブな場合は、sys.last_tracebackとしてユーザーが利用できるようになります。

明示的に作成されたトレースバックの場合、フルスタックトレースを形成するためにtb_next属性をリンクする方法を決定するのはトレースバックの作成者次第です。

特別な読み取り専用属性:tb_frameは、現在のレベルの実行フレームを指します。 tb_linenoは、例外が発生した行番号を示します。 tb_lastiは正確な指示を示します。 一致するexcept句がない、またはfinally句がある try ステートメントで例外が発生した場合、トレースバックの行番号と最後の命令がフレームオブジェクトの行番号と異なる場合があります。

tb_frameにアクセスすると、監査イベント object.__getattr__が引数objおよび"tb_frame"で発生します。

特別な書き込み可能な属性:tb_nextは、スタックトレースの次のレベル(例外が発生したフレームに向かって)、または次のレベルがない場合はNoneです。

バージョン3.7での変更: TracebackオブジェクトをPythonコードから明示的にインスタンス化できるようになり、既存のインスタンスのtb_next属性を更新できるようになりました。

オブジェクトをスライスする

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

特別な読み取り専用属性:startは下限です。 stopは上限です。 stepはステップ値です。 省略した場合、それぞれがNoneになります。 これらの属性は任意のタイプにすることができます。

スライスオブジェクトは次の1つのメソッドをサポートします。

slice.indices(self, length)

このメソッドは、単一の整数引数 length を取り、 length アイテムのシーケンスに適用された場合にスライスオブジェクトが記述するスライスに関する情報を計算します。 3つの整数のタプルを返します。 それぞれ、 start および stop インデックスと、 step またはスライスのストライド長です。 欠落または範囲外のインデックスは、通常のスライスと一致する方法で処理されます。

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

静的メソッドオブジェクトは、関数オブジェクトから上記のメソッドオブジェクトへの変換を無効にする方法を提供します。 静的メソッドオブジェクトは、他のオブジェクト(通常はユーザー定義のメソッドオブジェクト)のラッパーです。 静的メソッドオブジェクトがクラスまたはクラスインスタンスから取得されると、実際に返されるオブジェクトはラップされたオブジェクトであり、それ以上の変換は行われません。 静的メソッドオブジェクト自体は呼び出すことができませんが、ラップするオブジェクトは通常呼び出すことができます。 静的メソッドオブジェクトは、組み込みの staticmethod()コンストラクターによって作成されます。

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

クラスメソッドオブジェクトは、静的メソッドオブジェクトと同様に、別のオブジェクトのラッパーであり、そのオブジェクトがクラスおよびクラスインスタンスから取得される方法を変更します。 このような取得時のクラスメソッドオブジェクトの動作については、上記の「ユーザー定義メソッド」で説明しています。 クラスメソッドオブジェクトは、組み込みの classmethod()コンストラクターによって作成されます。


3.3。 特別なメソッド名

クラスは、特別な名前でメソッドを定義することにより、特別な構文(算術演算、添え字、スライスなど)によって呼び出される特定の操作を実装できます。 これは、演算子のオーバーロードに対するPythonのアプローチであり、クラスが言語演算子に関して独自の動作を定義できるようにします。 たとえば、クラスが__getitem__()という名前のメソッドを定義し、xがこのクラスのインスタンスである場合、x[i]type(x).__getitem__(x, i)とほぼ同等です。 特に明記されている場合を除き、適切なメソッドが定義されていない場合(通常、 AttributeError または TypeError )、操作を実行しようとすると例外が発生します。

特別な方法をNoneに設定すると、対応する操作が利用できないことを示します。 たとえば、クラスが__iter__()Noneに設定する場合、そのクラスは反復可能ではないため、そのインスタンスで iter()を呼び出すと、 TypeError が発生します。 ](__getitem__()にフォールバックせずに)。 2

組み込み型をエミュレートするクラスを実装する場合、モデル化されるオブジェクトにとって意味のある範囲でのみエミュレーションを実装することが重要です。 たとえば、一部のシーケンスは個々の要素の取得でうまく機能する場合がありますが、スライスを抽出しても意味がない場合があります。 (この一例は、W3CのドキュメントオブジェクトモデルのNodeListインターフェイスです。)

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

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

クラス cls の新しいインスタンスを作成するために呼び出されます。 __ new __()は、インスタンスが要求されたクラスを最初の引数として受け取る静的メソッド(特殊なケースであるため、そのように宣言する必要はありません)です。 残りの引数は、オブジェクトコンストラクター式(クラスの呼び出し)に渡される引数です。 __ new __()の戻り値は、新しいオブジェクトインスタンス(通常は cls のインスタンス)である必要があります。

一般的な実装では、適切な引数を指定してsuper().__new__(cls[, ...])を使用してスーパークラスの __ new __()メソッドを呼び出し、新しく作成されたインスタンスを必要に応じて変更してから返すことで、クラスの新しいインスタンスを作成します。

オブジェクトの構築中に __ new __()が呼び出され、 cls のインスタンスが返される場合、新しいインスタンスの __ init __()メソッドは__init__(self[, ...])、ここで self は新しいインスタンスであり、残りの引数はオブジェクトコンストラクターに渡されたものと同じです。

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

__ new __()は、主に不変型のサブクラス(int、str、tupleなど)がインスタンスの作成をカスタマイズできるようにすることを目的としています。 また、クラスの作成をカスタマイズするために、カスタムメタクラスでも一般的にオーバーライドされます。

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

インスタンスが作成された後( __ new __()によって)、インスタンスが呼び出し元に返される前に呼び出されます。 引数は、クラスコンストラクター式に渡される引数です。 基本クラスに __ init __()メソッドがある場合、派生クラスの __ init __()メソッドがある場合は、インスタンスの基本クラス部分が適切に初期化されるように、明示的に呼び出す必要があります。 ; 例:super().__init__([args...])

__ new __()__ init __()は連携してオブジェクトを構築するため( __ new __()はそれを作成し、 __ init __()はカスタマイズ)、 __ init __()によってNone以外の値が返されることはありません。 これを行うと、実行時に TypeError が発生します。

object.__del__(self)

インスタンスが破棄されようとしているときに呼び出されます。 これは、ファイナライザーまたは(不適切に)デストラクタとも呼ばれます。 基本クラスに __ del __()メソッドがある場合、派生クラスの __ del __()メソッドがある場合は、インスタンスの基本クラス部分が適切に削除されるように、明示的に呼び出す必要があります。 。

__ del __()メソッドは、インスタンスへの新しい参照を作成することにより、インスタンスの破棄を延期することができます(推奨されません!)。 これはオブジェクト復活と呼ばれます。 復活したオブジェクトが破壊されようとしているときに __ del __()が2回呼び出されるかどうかは、実装によって異なります。 現在の CPython 実装は、それを1回だけ呼び出します。

__ del __()メソッドが、インタープリターの終了時にまだ存在するオブジェクトに対して呼び出されることは保証されていません。

ノート

del xx.__del__()を直接呼び出しません—前者はxの参照カウントを1つ減らし、後者はxの参照の場合にのみ呼び出されますカウントがゼロになります。

警告

__ del __()メソッドが呼び出されるという不安定な状況のため、実行中に発生した例外は無視され、代わりにsys.stderrに警告が出力されます。 特に:

  • __ del __()は、任意のスレッドからの実行を含め、任意のコードが実行されているときに呼び出すことができます。 __ del __()がロックを取得するか、他のブロッキングリソースを呼び出す必要がある場合、 __ del __()の実行が中断されるコードによってリソースがすでに取得されている可能性があるため、デッドロックが発生する可能性があります。

  • __ del __()は、インタープリターのシャットダウン中に実行できます。 結果として、アクセスする必要のあるグローバル変数(他のモジュールを含む)はすでに削除されているか、Noneに設定されている可能性があります。 Pythonは、名前が1つのアンダースコアで始まるグローバルが、他のグローバルが削除される前にモジュールから削除されることを保証します。 そのようなグローバルへの他の参照が存在しない場合、これは、 __ del __()メソッドが呼び出されたときにインポートされたモジュールが引き続き使用可能であることを保証するのに役立つ場合があります。


object.__repr__(self)

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

これは通常、デバッグに使用されるため、表現が情報が豊富で明確であることが重要です。

object.__str__(self)

str(object)と組み込み関数 format()および print()によって呼び出され、物体。 戻り値は string オブジェクトである必要があります。

このメソッドは、 __ str __()が有効なPython式を返すことを期待しないという点で、 object .__ repr __()とは異なります。より便利で簡潔な表現を使用できます。

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

object.__bytes__(self)

オブジェクトのバイト文字列表現を計算するために bytes によって呼び出されます。 これにより、 bytes オブジェクトが返されます。

object.__format__(self, format_spec)

format()組み込み関数、ひいては形式の文字列リテラルおよび str.format()メソッドの評価によって呼び出され、オブジェクトの「フォーマットされた」文字列表現。 format_spec 引数は、必要なフォーマットオプションの説明を含む文字列です。 format_spec 引数の解釈は、 __ format __()を実装する型次第ですが、ほとんどのクラスは、組み込み型の1つにフォーマットを委任するか、同様のフォーマットオプションを使用します。構文。

標準のフォーマット構文の説明については、フォーマット仕様ミニ言語を参照してください。

戻り値は文字列オブジェクトである必要があります。

バージョン3.4で変更: objectの__format__メソッド自体は、空でない文字列が渡されると TypeError を発生させます。

バージョン3.7で変更: object.__format__(x, )は、format(str(self), )ではなく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)

これらは、いわゆる「リッチ比較」方法です。 演算子記号とメソッド名の対応は次のとおりです。x<yx.__lt__(y)を呼び出し、x<=yx.__le__(y)を呼び出し、x==yx.__eq__(y)x!=yx.__ne__(y)を呼び出し、x>yx.__gt__(y)を呼び出し、x>=yx.__ge__(y)を呼び出します。

豊富な比較メソッドは、指定された引数のペアに対する操作を実装していない場合、シングルトンNotImplementedを返す可能性があります。 慣例により、比較が成功すると、FalseTrueが返されます。 ただし、これらのメソッドは任意の値を返すことができるため、比較演算子がブールコンテキストで使用される場合(たとえば、ifステートメントの条件で)、Pythonは bool()を呼び出します。結果がtrueかfalseかを判別するための値。

デフォルトでは、objectisを使用して __ eq __()を実装し、誤った比較の場合はNotImplementedを返します:True if x is y else NotImplemented__ ne __()の場合、デフォルトでは __ eq __()に委任され、NotImplementedでない限り結果が反転されます。 比較演算子またはデフォルトの実装の間には、他に暗黙の関係はありません。 たとえば、(x<y or x==y)の真実は、x<=yを意味するものではありません。 単一のルート操作から順序付け操作を自動的に生成するには、 functools.total_ordering()を参照してください。

カスタム比較操作をサポートし、辞書キーとして使用できる hashable オブジェクトの作成に関する重要な注意事項については、 __ hash __()の段落を参照してください。

これらのメソッドのスワップ引数バージョンはありません(左の引数が操作をサポートしていないが、右の引数はサポートしている場合に使用されます)。 むしろ、 __ lt __()__ gt __()はお互いの反射であり、 __ le __()__ ge __()はお互いの反射です。 __ eq __()__ ne __()はそれぞれ独自の反射です。 オペランドのタイプが異なり、右のオペランドのタイプが左のオペランドのタイプの直接または間接のサブクラスである場合、右のオペランドの反映されたメソッドが優先されます。それ以外の場合は、左のオペランドのメソッドが優先されます。 仮想サブクラス化は考慮されません。

object.__hash__(self)

組み込み関数 hash()によって呼び出され、 setfrozensetdict などのハッシュコレクションのメンバーを操作します。 __ hash __()は整数を返す必要があります。 唯一必要なプロパティは、等しいと比較するオブジェクトが同じハッシュ値を持つことです。 オブジェクトをタプルにパックしてタプルをハッシュすることにより、オブジェクトの比較でも役割を果たすオブジェクトのコンポーネントのハッシュ値を混合することをお勧めします。 例:

def __hash__(self):
    return hash((self.name, self.nick, self.color))

ノート

hash()は、オブジェクトのカスタム __ hash __()メソッドから返された値をPy_ssize_tのサイズに切り捨てます。 これは通常、64ビットビルドでは8バイト、32ビットビルドでは4バイトです。 オブジェクトの __ hash __()が異なるビットサイズのビルドで相互運用する必要がある場合は、サポートされているすべてのビルドの幅を確認してください。 これを行う簡単な方法は、python -c "import sys; print(sys.hash_info.width)"を使用することです。

クラスが __ eq __()メソッドを定義しない場合、 __ hash __()操作も定義しないでください。 __ eq __()を定義しているが、 __ hash __()を定義していない場合、そのインスタンスはハッシュ可能なコレクションのアイテムとして使用できません。 クラスが可変オブジェクトを定義し、 __ eq __()メソッドを実装する場合、ハッシュ可能なコレクションの実装ではキーのハッシュ値が不変である必要があるため、 __ hash __()を実装しないでください(オブジェクトのハッシュ値が変更されると、間違ったハッシュバケットに入れられます)。

ユーザー定義クラスには、デフォルトで __ eq __()および __ hash __()メソッドがあります。 それらを使用すると、すべてのオブジェクトは(それ自体を除いて)等しくなく比較され、x.__hash__()は、x == yx is yhash(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)呼び出しによってハッシュ可能として誤って識別されます。

ノート

デフォルトでは、strおよびbytesオブジェクトの __ hash __()値は、予測できないランダム値で「ソルト」されます。 それらは個々のPythonプロセス内で一定のままですが、Pythonを繰り返し呼び出す間で予測することはできません。

これは、dict挿入の最悪の場合のパフォーマンスであるO(n ^ 2)の複雑さを悪用する、慎重に選択された入力によって引き起こされるサービス拒否に対する保護を提供することを目的としています。 詳細については、 http://www.ocert.org/advisories/ocert-2011-003.htmlを参照してください。

ハッシュ値を変更すると、セットの反復順序に影響します。 Pythonは、この順序について保証したことはありません(通常、32ビットビルドと64ビットビルドの間で異なります)。

PYTHONHASHSEED も参照してください。

バージョン3.3で変更:ハッシュのランダム化はデフォルトで有効になっています。

object.__bool__(self)
真理値テストと組み込み操作bool()を実装するために呼び出されます。 FalseまたはTrueを返す必要があります。 このメソッドが定義されていない場合、 __ len __()が定義されている場合は呼び出され、結果がゼロ以外の場合はオブジェクトはtrueと見なされます。 クラスが __ len __()__ bool __()も定義していない場合、そのすべてのインスタンスはtrueと見なされます。


3.3.2。 属性アクセスのカスタマイズ

次のメソッドを定義して、クラスインスタンスの属性アクセス(x.nameの使用、割り当て、または削除)の意味をカスタマイズできます。

object.__getattr__(self, name)

デフォルトの属性アクセスが AttributeError で失敗した場合に呼び出されます( name はインスタンス属性ではないため、 __ getattribute __()AttributeError を発生させます。 self;または name プロパティの __ get __()のクラスツリーの属性は、 AttributeError )を発生させます。 このメソッドは、(計算された)属性値を返すか、 AttributeError 例外を発生させる必要があります。

通常のメカニズムで属性が見つかった場合、 __ getattr __()は呼び出されないことに注意してください。 (これは、 __ getattr __()__ setattr __()の間の意図的な非対称性です。)これは、効率上の理由と、そうでない場合は __ getattr __()にはないためです。インスタンスの他の属性にアクセスする方法。 少なくともインスタンス変数の場合、インスタンス属性ディクショナリに値を挿入しない(代わりに別のオブジェクトに値を挿入する)ことで、完全な制御を偽造できることに注意してください。 属性アクセスを実際に完全に制御する方法については、以下の __ getattribute __()メソッドを参照してください。

object.__getattribute__(self, name)

クラスのインスタンスの属性アクセスを実装するために無条件に呼び出されます。 クラスが __ 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。 モジュール属性アクセスのカスタマイズ

特別な名前__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__の設定は、属性アクセス構文を使用して行われたルックアップにのみ影響します。モジュールグローバルに直接アクセスします(モジュール内のコードまたはモジュールのグローバルディクショナリへの参照を介して)。影響を受けません。


バージョン3.5で変更: __class__モジュール属性が書き込み可能になりました。


バージョン3.7の新機能: __getattr__および__dir__モジュール属性。


も参照してください

PEP 562 -モジュール__getattr__および__dir__
モジュールの__getattr__および__dir__機能について説明します。


3.3.2.2。 記述子の実装

次のメソッドは、メソッドを含むクラスのインスタンス(いわゆる記述子クラス)が所有者クラスにある場合にのみ適用されます(記述子は所有者のクラスディクショナリのいずれかにある必要があります)またはその親の1つのクラス辞書にあります)。 以下の例では、「属性」とは、所有者クラスの __ dict __ のプロパティのキーを名前とする属性を指します。

object.__get__(self, instance, owner=None)

所有者クラスの属性(クラス属性アクセス)またはそのクラスのインスタンスの属性(インスタンス属性アクセス)を取得するために呼び出されます。 オプションの owner 引数は所有者クラスであり、 instance は属性がアクセスされたインスタンス、または属性がを介してアクセスされた場合はNoneです。所有者

このメソッドは、計算された属性値を返すか、 AttributeError 例外を発生させる必要があります。

PEP 252 は、 __ get __()が1つまたは2つの引数で呼び出し可能であることを指定します。 Python独自の組み込み記述子は、この仕様をサポートしています。 ただし、一部のサードパーティツールには、両方の引数を必要とする記述子がある可能性があります。 Python独自の __ getattribute __()実装は、必須かどうかに関係なく、常に両方の引数を渡します。

object.__set__(self, instance, value)

所有者クラスのインスタンスインスタンスの属性を新しい値に設定するために呼び出されます。

__ set __()または __ delete __()を追加すると、記述子の種類が「データ記述子」に変更されることに注意してください。 詳細については、記述子の呼び出しを参照してください。

object.__delete__(self, instance)
所有者クラスのインスタンスインスタンスの属性を削除するために呼び出されます。
object.__set_name__(self, owner, name)

所有クラス owner が作成されたときに呼び出されます。 記述子は name に割り当てられています。

ノート

__ set_name __()は、 type コンストラクターの一部として暗黙的に呼び出されるだけなので、最初の作成後に記述子がクラスに追加されるときに、適切なパラメーターを使用して明示的に呼び出す必要があります。

class A:
   pass
descr = custom_descriptor()
A.attr = descr
descr.__set_name__(A, 'attr')

詳細については、クラスオブジェクトの作成を参照してください。

バージョン3.6の新機能。

属性__objclass__は、 inspect モジュールによって、このオブジェクトが定義されたクラスを指定するものとして解釈されます(これを適切に設定すると、動的クラス属性の実行時のイントロスペクションに役立ちます)。 呼び出し可能オブジェクトの場合、指定されたタイプ(またはサブクラス)のインスタンスが最初の位置引数として予期または必要であることを示している場合があります(たとえば、CPythonはCで実装されている非バインドメソッドにこの属性を設定します)。


3.3.2.3。 記述子の呼び出し

一般に、記述子は「バインディング動作」を持つオブジェクト属性であり、その属性アクセスは記述子プロトコルのメソッド__get__()__set__()、および__delete__()によってオーバーライドされています。 。 これらのメソッドのいずれかがオブジェクトに対して定義されている場合、それは記述子であると言われます。

属性アクセスのデフォルトの動作は、オブジェクトのディクショナリから属性を取得、設定、または削除することです。 たとえば、a.xには、a.__dict__['x']type(a).__dict__['x']の順に始まり、メタクラスを除くtype(a)の基本クラスまで続くルックアップチェーンがあります。

ただし、ルックアップされた値が記述子メソッドの1つを定義するオブジェクトである場合、Pythonはデフォルトの動作をオーバーライドし、代わりに記述子メソッドを呼び出すことがあります。 優先順位チェーンのどこでこれが発生するかは、定義された記述子メソッドとそれらがどのように呼び出されたかによって異なります。

記述子呼び出しの開始点は、バインディングa.xです。 引数がどのように組み立てられるかは、aによって異なります。

直接電話
最も単純で最も一般的でない呼び出しは、ユーザーコードが記述子メソッドx.__get__(a)を直接呼び出す場合です。
インスタンスバインディング
オブジェクトインスタンスにバインドする場合、a.xは呼び出しtype(a).__dict__['x'].__get__(a, type(a))に変換されます。
クラスバインディング
クラスにバインドする場合、A.xは呼び出しA.__dict__['x'].__get__(None, A)に変換されます。
スーパーバインディング
asuper のインスタンスである場合、バインディングsuper(B, obj).m()obj.__class__.__mro__B次に、A.__dict__['m'].__get__(obj, obj.__class__)の呼び出しで記述子を呼び出します。

インスタンスバインディングの場合、記述子呼び出しの優先順位は、定義されている記述子メソッドによって異なります。 記述子は、__get__()__set__()、および__delete__()の任意の組み合わせを定義できます。 __get__()が定義されていない場合、オブジェクトのインスタンスディクショナリに値がない限り、属性にアクセスすると記述子オブジェクト自体が返されます。 記述子が__set__()および/または__delete__()を定義している場合、それはデータ記述子です。 どちらも定義していない場合は、非データ記述子です。 通常、データ記述子は__get__()__set__()の両方を定義しますが、非データ記述子は__get__()メソッドのみを持ちます。 __set__()および__get__()が定義されたデータ記述子は、常にインスタンスディクショナリの再定義を上書きします。 対照的に、非データ記述子はインスタンスによってオーバーライドできます。

Pythonメソッド( staticmethod()および classmethod()を含む)は、非データ記述子として実装されます。 したがって、インスタンスはメソッドを再定義してオーバーライドできます。 これにより、個々のインスタンスが同じクラスの他のインスタンスとは異なる動作を取得できるようになります。

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


3.3.2.4。 __slots__

__ slots __ を使用すると、データメンバー(プロパティなど)を明示的に宣言し、 __ dict __ および __ weakref __ の作成を拒否できます( __ slots __ で明示的に宣言されている場合を除く)または親で利用可能です。)

__ dict __ を使用して節約されたスペースはかなりの量になる可能性があります。 属性のルックアップ速度も大幅に向上する可能性があります。

object.__slots__
このクラス変数には、インスタンスで使用される変数名を持つ文字列、反復可能、または文字列のシーケンスを割り当てることができます。 __ slots __ は、宣言された変数用のスペースを予約し、インスタンスごとに __ dict __ および __ weakref __ が自動的に作成されないようにします。
3.3.2.4.1。 使用上の注意 __slots__
  • __ slots __ のないクラスから継承する場合、インスタンスの __ dict __ および __ weakref __ 属性は常にアクセス可能です。
  • __ dict __ 変数がないと、 __ slots __ 定義にリストされていない新しい変数をインスタンスに割り当てることはできません。 リストされていない変数名に割り当てようとすると、 AttributeError が発生します。 新しい変数の動的な割り当てが必要な場合は、 __ slots __ 宣言の文字列のシーケンスに'__dict__'を追加します。
  • 各インスタンスに __ weakref __ 変数がない場合、 __ slots __ を定義するクラスはそのインスタンスへの弱参照をサポートしません。 弱参照のサポートが必要な場合は、 __ slot __ 宣言の文字列のシーケンスに'__weakref__'を追加します。
  • __ slots __ は、変数名ごとに記述子( Implementation Descriptors )を作成することにより、クラスレベルで実装されます。 その結果、クラス属性を使用して、 __ slots __ で定義されたインスタンス変数のデフォルト値を設定することはできません。 そうしないと、クラス属性が記述子の割り当てを上書きします。
  • __ slots __ 宣言のアクションは、それが定義されているクラスに限定されません。 親で宣言された __ slots __ は、子クラスで使用できます。 ただし、子サブクラスは、 __ slot __追加スロットの名前のみを含む必要があります)も定義しない限り、 __ dict __ および __ weakref __ を取得します。 。
  • クラスが基本クラスでも定義されているスロットを定義している場合、基本クラススロットで定義されているインスタンス変数にアクセスできません(基本クラスから直接記述子を取得する場合を除く)。 これにより、プログラムの意味が未定義になります。 将来的には、これを防ぐためにチェックが追加される可能性があります。
  • 空でない __ slots __ は、 intbytestuple などの「可変長」組み込み型から派生したクラスでは機能しません。
  • 文字列以外の反復可能オブジェクトは、 __ slots __ に割り当てることができます。 マッピングも使用できます。 ただし、将来的には、各キーに対応する値に特別な意味が割り当てられる可能性があります。
  • __ class __ の割り当ては、両方のクラスが同じ __ slot __ を持っている場合にのみ機能します。
  • 複数のスロット付き親クラスを持つ多重継承を使用できますが、スロットによって作成された属性を持つことができるのは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の新機能。

3.3.3.1。 メタクラス

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

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

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass

クラス定義で指定されているその他のキーワード引数は、以下で説明するすべてのメタクラス操作に渡されます。

クラス定義が実行されると、次の手順が実行されます。

  • MROエントリが解決されます。
  • 適切なメタクラスが決定されます。
  • クラス名前空間が準備されます。
  • クラス本体が実行されます。
  • クラスオブジェクトが作成されます。


3.3.3.2。 MROエントリの解決

クラス定義に表示されるベースが type のインスタンスでない場合は、__mro_entries__メソッドが検索されます。 見つかった場合は、元のベースタプルで呼び出されます。 このメソッドは、このベースの代わりに使用されるクラスのタプルを返す必要があります。 タプルは空である可能性があり、その場合、元のベースは無視されます。

も参照してください

PEP 560 -タイピングモジュールとジェネリック型のコアサポート


3.3.3.3。 適切なメタクラスの決定

クラス定義の適切なメタクラスは、次のように決定されます。

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

最も派生したメタクラスは、明示的に指定されたメタクラス(存在する場合)とメタクラス(つまり、 指定されたすべての基本クラスのtype(cls))。 最も派生したメタクラスは、これらの候補メタクラスの all のサブタイプであるメタクラスです。 候補メタクラスのいずれもその基準を満たさない場合、クラス定義はTypeErrorで失敗します。


3.3.3.4。 クラス名前空間の準備

適切なメタクラスが特定されると、クラスの名前空間が準備されます。 メタクラスに__prepare__属性がある場合、それはnamespace = metaclass.__prepare__(name, bases, **kwds)と呼ばれます(追加のキーワード引数がある場合は、クラス定義から取得されます)。 __prepare__メソッドは、 classmethod()として実装する必要があります。 __prepare__によって返される名前空間は__new__に渡されますが、最終的なクラスオブジェクトが作成されると、名前空間は新しいdictにコピーされます。

メタクラスに__prepare__属性がない場合、クラスの名前空間は空の順序付きマッピングとして初期化されます。

も参照してください

PEP 3115 -Python3000のメタクラス
__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()のゼロ引数形式は、字句スコープに基づいて定義されているクラスを正しく識別できますが、現在の呼び出しを行うために使用されたクラスまたはインスタンスは、に渡された最初の引数に基づいて識別されます。メソッド。

デフォルトのメタクラス type 、または最終的にtype.__new__を呼び出すメタクラスを使用する場合、クラスオブジェクトの作成後に、次の追加のカスタマイズ手順が呼び出されます。

  • まず、type.__new__は、 __ set_name __()メソッドを定義するクラス名前空間内のすべての記述子を収集します。
  • 次に、これらの__set_name__メソッドはすべて、定義されているクラスとその特定の記述子の割り当てられた名前で呼び出されます。
  • 最後に、 __ init_subclass __()フックが、メソッド解決順序で新しいクラスの直接の親に対して呼び出されます。

クラスオブジェクトが作成された後、それはクラス定義(存在する場合)に含まれるクラスデコレータに渡され、結果のオブジェクトは定義されたクラスとしてローカル名前空間にバインドされます。

type.__new__によって新しいクラスが作成されると、名前空間パラメーターとして提供されたオブジェクトが新しい順序付きマッピングにコピーされ、元のオブジェクトは破棄されます。 新しいコピーは読み取り専用プロキシにラップされ、クラスオブジェクトの __ dict __ 属性になります。

も参照してください

PEP 3135 -新しいスーパー
暗黙の__class__クロージャ参照について説明します


3.3.3.7。 メタクラスの用途

メタクラスの潜在的な用途は無限です。 検討されてきたいくつかのアイデアには、列挙型、ロギング、インターフェースチェック、自動委任、自動プロパティ作成、プロキシ、フレームワーク、および自動リソースロック/同期が含まれます。


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

次のメソッドは、 isinstance()および issubclass()組み込み関数のデフォルトの動作をオーバーライドするために使用されます。

特に、メタクラス abc.ABCMeta は、これらのメソッドを実装して、抽象基本クラス(ABC)を「仮想基本クラス」として任意のクラスまたはタイプ(組み込み型を含む)に追加できるようにします。他のABC。

class.__instancecheck__(self, instance)
instanceclass の(直接または間接の)インスタンスと見なす必要がある場合は、trueを返します。 定義されている場合、isinstance(instance, class)を実装するために呼び出されます。
class.__subclasscheck__(self, subclass)
サブクラスクラスの(直接または間接)サブクラスと見なす必要がある場合は、trueを返します。 定義されている場合、issubclass(subclass, class)を実装するために呼び出されます。

これらのメソッドは、クラスのタイプ(メタクラス)で検索されることに注意してください。 実際のクラスのクラスメソッドとして定義することはできません。 これは、インスタンスで呼び出される特別なメソッドのルックアップと一致しています。この場合のみ、インスタンス自体がクラスです。

も参照してください

PEP 3119 -抽象基本クラスの紹介
isinstance()および issubclass()の動作を __ instancecheck __()および __ subclasscheck __()を通じてカスタマイズするための仕様が含まれています。言語に抽象基本クラス( abc モジュールを参照)を追加するコンテキストでの機能。


3.3.5。 ジェネリック型のエミュレート

特別なメソッドを定義することにより、 PEP 484 (たとえば、List[int])で指定されたジェネリッククラス構文を実装できます。

classmethod object.__class_getitem__(cls, key)
key にある型引数によるジェネリッククラスの特殊化を表すオブジェクトを返します。

このメソッドはクラスオブジェクト自体で検索され、クラス本体で定義されている場合、このメソッドは暗黙的にクラスメソッドです。 このメカニズムは主に静的タイプのヒントで使用するために予約されていることに注意してください。他の使用はお勧めしません。

も参照してください

PEP 560 -タイピングモジュールとジェネリック型のコアサポート


3.3.6。 呼び出し可能なオブジェクトのエミュレート

object.__call__(self[, args...])
インスタンスが関数として「呼び出される」ときに呼び出されます。 このメソッドが定義されている場合、x(arg1, arg2, ...)はおおよそ[X111X] に変換されます。


3.3.7。 コンテナタイプのエミュレート

コンテナオブジェクトを実装するには、次のメソッドを定義できます。 コンテナは通常、シーケンス(リストやタプルなど)またはマッピング(辞書など)ですが、他のコンテナを表すこともできます。 メソッドの最初のセットは、シーケンスをエミュレートするか、マッピングをエミュレートするために使用されます。 違いは、シーケンスの場合、許容されるキーは整数 k である必要があることです。0 <= k < Nここで、 N はシーケンスの長さ、またはスライスオブジェクトです。アイテムの範囲を定義します。 また、マッピングでメソッドkeys()values()items()get()clear()setdefault()を提供することをお勧めします。 、pop()popitem()copy()、およびupdate()は、Pythonの標準辞書オブジェクトと同様に動作します。 collections.abc モジュールは、 MutableMapping 抽象基本クラスを提供し、__getitem__()__setitem__()__delitem__()、およびkeys()。 可変シーケンスは、メソッドappend()count()index()extend()insert()pop()remove()reverse()sort()、Python標準リストオブジェクトと同様。 最後に、シーケンスタイプは、メソッド__add__()__radd__()__iadd__()__mul__()、[以下に説明するX190X] および__imul__()。 他の数値演算子を定義するべきではありません。 in演算子を効率的に使用できるように、マッピングとシーケンスの両方で__contains__()メソッドを実装することをお勧めします。 マッピングの場合、inはマッピングのキーを検索する必要があります。 シーケンスの場合は、値を検索する必要があります。 さらに、マッピングとシーケンスの両方で__iter__()メソッドを実装して、コンテナーを効率的に反復できるようにすることをお勧めします。 マッピングの場合、__iter__()はオブジェクトのキーを反復処理する必要があります。 シーケンスの場合、値を反復処理する必要があります。

object.__len__(self)
組み込み関数 len()を実装するために呼び出されます。 オブジェクトの長さ、整数>= 0を返す必要があります。 また、 __ bool __()メソッドを定義せず、 __ len __()メソッドがゼロを返すオブジェクトは、ブールコンテキストではfalseと見なされます。
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]の評価を実装するために呼び出されます。 シーケンスタイプの場合、受け入れられるキーは整数とスライスオブジェクトである必要があります。 負のインデックスの特別な解釈(クラスがシーケンスタイプをエミュレートする場合)は、 __ getitem __()メソッド次第であることに注意してください。 key が不適切なタイプの場合、 TypeError が発生する可能性があります。 シーケンスのインデックスのセット外の値の場合(負の値の特別な解釈の後)、 IndexError を発生させる必要があります。 マッピングタイプの場合、 key が(コンテナにない)欠落していると、 KeyError が発生するはずです。

ノート

for ループは、シーケンスの終わりを適切に検出できるように、不正なインデックスに対して IndexError が発生することを想定しています。

object.__setitem__(self, key, value)
self[key]への割り当てを実装するために呼び出されます。 __ getitem __()と同じ注意。 これは、オブジェクトがキーの値の変更をサポートしている場合、新しいキーを追加できる場合、または要素を置き換えることができる場合はシーケンスの場合にのみ、マッピングに実装する必要があります。 __ getitem __()メソッドの場合と同じ例外が、不適切な key 値に対して発生する必要があります。
object.__delitem__(self, key)
self[key]の削除を実装するために呼び出されます。 __ getitem __()と同じ注意。 これは、オブジェクトがキーの削除をサポートしている場合のマッピング、または要素をシーケンスから削除できる場合のシーケンスに対してのみ実装する必要があります。 __ getitem __()メソッドの場合と同じ例外が、不適切な key 値に対して発生する必要があります。
object.__missing__(self, key)
キーがディクショナリにない場合にdictサブクラスにself[key]を実装するために、 dict__ getitem __()によって呼び出されます。
object.__iter__(self)

このメソッドは、コンテナーにイテレーターが必要な場合に呼び出されます。 このメソッドは、コンテナ内のすべてのオブジェクトを反復処理できる新しいイテレータオブジェクトを返す必要があります。 マッピングの場合、コンテナのキーを反復処理する必要があります。

イテレータオブジェクトもこのメソッドを実装する必要があります。 彼らは自分自身を返す必要があります。 イテレータオブジェクトの詳細については、イテレータタイプを参照してください。

object.__reversed__(self)

reverse()ビルトインによって呼び出され(存在する場合)、逆反復を実装します。 コンテナ内のすべてのオブジェクトを逆の順序で繰り返す新しいイテレータオブジェクトを返す必要があります。

__ reverse __()メソッドが提供されていない場合、 reverse()ビルトインは、シーケンスプロトコル( __ len __()およびの使用にフォールバックします。 ] __ getitem __())。 シーケンスプロトコルをサポートするオブジェクトは、 reverse()によって提供されるものよりも効率的な実装を提供できる場合にのみ、 __ reversesed __()を提供する必要があります。

メンバーシップテスト演算子( in および not in )は、通常、コンテナーを介した反復として実装されます。 ただし、コンテナオブジェクトは、より効率的な実装で次の特別なメソッドを提供できます。これも、オブジェクトが反復可能である必要はありません。

object.__contains__(self, item)

メンバーシップテスト演算子を実装するために呼び出されます。 itemself にある場合はtrueを返し、そうでない場合はfalseを返す必要があります。 オブジェクトのマッピングの場合、値やキーとアイテムのペアではなく、マッピングのキーを考慮する必要があります。

__ 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)

これらのメソッドは、2進算術演算(+-*@/、 [ X131X]、%divmod()pow()**<<>>&^|)。 たとえば、式x + yを評価するために、 x__ add __()メソッドを持つクラスのインスタンスであり、x.__add__(y)が呼び出されます。 。 __ divmod __()メソッドは、 __ floordiv __()および __ mod __()を使用するのと同等である必要があります。 __ truediv __()とは関係ありません。 組み込みの pow()関数の3項バージョンをサポートする場合は、オプションの3番目の引数を受け入れるように __ pow __()を定義する必要があることに注意してください。

これらのメソッドの1つが、指定された引数を使用した操作をサポートしていない場合は、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)

これらのメソッドは、2進算術演算(+-*@/、 [ X131X]、%divmod()pow()**<<>>&^|)、反映された(スワップされた)オペランド。 これらの関数は、左側のオペランドが対応する演算 3 をサポートしておらず、オペランドのタイプが異なる場合にのみ呼び出されます。 4 たとえば、式x - yを評価するには、 y は、 __ rsub __()メソッドを持つクラスのインスタンスです。 X154X] は、x.__sub__(y)NotImplemented を返す場合に呼び出されます。

三項 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)

これらのメソッドは、拡張された算術割り当て(+=-=*=@=/=、 [ X135X]、%=**=<<=>>=&=^=、 [X217X ])。 これらのメソッドは、その場で操作を実行し( self を変更)、結果を返す必要があります( self である可能性がありますが、そうである必要はありません)。 特定のメソッドが定義されていない場合、拡張された割り当ては通常のメソッドにフォールバックします。 たとえば、 x__ iadd __()メソッドを持つクラスのインスタンスである場合、x += yx = x.__iadd__(y)と同等です。 それ以外の場合は、x + yの評価と同様に、x.__add__(y)およびy.__radd__(x)が考慮されます。 特定の状況では、拡張された割り当てによって予期しないエラーが発生する可能性があります(追加が機能するときにa_tuple [i] + = ['item']が例外を発生させる理由を参照)が、この動作は実際にはの一部です。データモデル。

ノート

**=のディスパッチメカニズムのバグにより、 __ ipow __()を定義するが、NotImplementedを返すクラスは、x.__pow__(y)にフォールバックできずy.__rpow__(x)。 このバグはPython3.10で修正されています。

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()、[ X141X] 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 )に切り捨てられたオブジェクトの値を返す必要があります。

__ int __()が定義されていない場合、組み込み関数 int()__ trunc __()にフォールバックします。


3.3.9。 ステートメントコンテキストマネージャーを使用

コンテキストマネージャーは、 with ステートメントを実行するときに確立されるランタイムコンテキストを定義するオブジェクトです。 コンテキストマネージャーは、コードブロックの実行に必要なランタイムコンテキストへのエントリと、そこからの出口を処理します。 コンテキストマネージャーは通常、withステートメント(セクション Withステートメントで説明)を使用して呼び出されますが、メソッドを直接呼び出すことによっても使用できます。

コンテキストマネージャーの一般的な使用法には、さまざまな種類のグローバル状態の保存と復元、リソースのロックとロック解除、開いているファイルのクローズなどがあります。

コンテキストマネージャーの詳細については、コンテキストマネージャーの種類を参照してください。

object.__enter__(self)
このオブジェクトに関連するランタイムコンテキストを入力します。 with ステートメントは、このメソッドの戻り値を、ステートメントのas句で指定されているターゲットにバインドします(存在する場合)。
object.__exit__(self, exc_type, exc_value, traceback)

このオブジェクトに関連するランタイムコンテキストを終了します。 パラメータは、コンテキストが終了する原因となった例外を記述します。 コンテキストが例外なく終了した場合、3つの引数はすべて None になります。

例外が提供され、メソッドが例外を抑制したい場合(つまり、例外が伝播されないようにしたい場合)、真の値を返す必要があります。 それ以外の場合、例外はこのメソッドの終了時に通常どおり処理されます。

__ exit __()メソッドは、渡された例外を再発生させてはならないことに注意してください。 これは発信者の責任です。

も参照してください

PEP 343 -「with」ステートメント
Python with ステートメントの仕様、背景、および例。


3.3.10。 特別なメソッドルックアップ

カスタムクラスの場合、特別なメソッドの暗黙的な呼び出しは、オブジェクトのインスタンスディクショナリではなく、オブジェクトのタイプで定義されている場合にのみ正しく機能することが保証されます。 この動作が、次のコードで例外が発生する理由です。

>>> 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__()など、型オブジェクトを含むすべてのオブジェクトによって実装されるいくつかの特別なメソッドにあります。 これらのメソッドの暗黙的なルックアップが従来のルックアッププロセスを使用した場合、型オブジェクト自体で呼び出されたときに失敗します。

>>> 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

この方法でクラスのバインドされていないメソッドを誤って呼び出そうとすると、「メタクラスの混乱」と呼ばれることがあり、特別なメソッドを検索するときにインスタンスをバイパスすることで回避されます。

>>> 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 オブジェクトは通常、__await__()メソッドを実装します。 async def 関数から返されるコルーチンオブジェクトが待機しています。

ノート

types.coroutine()または asyncio.coroutine()で装飾されたジェネレーターから返されるジェネレーターイテレーターオブジェクトも待機できますが、__await__()


object.__await__(self)
イテレータを返す必要があります。 awaitable オブジェクトを実装するために使用する必要があります。 たとえば、 asyncio.Future は、 await 式と互換性があるようにこのメソッドを実装します。

バージョン3.5の新機能。


も参照してください

PEP 492 で、待機可能なオブジェクトに関する追加情報を確認してください。


3.4.2。 コルーチンオブジェクト

コルーチンオブジェクト待機可能オブジェクトです。 コルーチンの実行は、__await__()を呼び出し、結果を反復処理することで制御できます。 コルーチンが実行を終了して戻ると、イテレータは StopIteration を発生させ、例外のvalue属性は戻り値を保持します。 コルーチンが例外を発生させた場合、それはイテレーターによって伝播されます。 コルーチンは、未処理の StopIteration 例外を直接発生させてはなりません。

コルーチンには、ジェネレーターのメソッドに類似した以下のメソッドもあります(ジェネレーター-イテレーターメソッドを参照)。 ただし、ジェネレーターとは異なり、コルーチンは反復を直接サポートしていません。

バージョン3.5.2で変更:コルーチンで複数回待機するのは RuntimeError です。


coroutine.send(value)
コルーチンの実行を開始または再開します。 valueNoneの場合、これは__await__()によって返されるイテレーターを進めることと同じです。 valueNoneでない場合、このメソッドは、コルーチンを中断させたイテレーターの send()メソッドに委任します。 結果(戻り値、 StopIteration 、またはその他の例外)は、上記の__await__()の戻り値を反復処理した場合と同じです。
coroutine.throw(type[, value[, traceback]])
コルーチンで指定された例外を発生させます。 このメソッドは、コルーチンを一時停止させたイテレータの throw()メソッドに委任します(そのようなメソッドがある場合)。 それ以外の場合は、一時停止ポイントで例外が発生します。 結果(戻り値、 StopIteration 、またはその他の例外)は、上記の__await__()の戻り値を反復処理した場合と同じです。 例外がコルーチンでキャッチされない場合、例外は呼び出し元に伝播します。
coroutine.close()

コルーチンがそれ自体をクリーンアップして終了するようにします。 コルーチンが一時停止されている場合、このメソッドは最初に、コルーチンを一時停止させたイテレーターの close()メソッドに委任します(そのようなメソッドがある場合)。 次に、サスペンションポイントで GeneratorExit を発生させ、コルーチンを即座にクリーンアップします。 最後に、コルーチンは、開始されていない場合でも、実行が終了したものとしてマークされます。

コルーチンオブジェクトは、破棄されようとしているときに、上記のプロセスを使用して自動的に閉じられます。


3.4.3。 非同期イテレータ

非同期イテレータは、__anext__メソッドで非同期コードを呼び出すことができます。

非同期イテレータは、 async for ステートメントで使用できます。

object.__aiter__(self)
非同期イテレータオブジェクトを返す必要があります。
object.__anext__(self)
イテレータの次の値をもたらす awaitable を返す必要があります。 反復が終了すると、 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。 非同期コンテキストマネージャー

非同期コンテキストマネージャーは、__aenter__および__aexit__メソッドで実行を一時停止できるコンテキストマネージャーです。

非同期コンテキストマネージャーは、 async with ステートメントで使用できます。

object.__aenter__(self)
__ enter __()と意味的に似ていますが、唯一の違いは、 awaitable を返さなければならないことです。
object.__aexit__(self, exc_type, exc_value, traceback)
__ exit __()と意味的に似ていますが、唯一の違いは、 awaitable を返さなければならないことです。

非同期コンテキストマネージャークラスの例:

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
特定の制御された条件下で、オブジェクトのタイプを変更できる場合があります。 ただし、正しく処理しないと非常に奇妙な動作を引き起こす可能性があるため、一般的にはお勧めできません。
2
__hash__()__iter__()__reversed__()、および__contains__()メソッドには、これに対する特別な処理があります。 他の人はまだ TypeError を発生させますが、Noneが呼び出せない動作に依存することで発生する可能性があります。
3
ここでの「サポートしない」とは、クラスにそのようなメソッドがないか、メソッドがNotImplementedを返すことを意味します。 右のオペランドの反映されたメソッドにフォールバックを強制する場合は、メソッドをNoneに設定しないでください。代わりに、そのようなフォールバックを明示的にブロックするのとは逆の効果があります。
4
同じタイプのオペランドの場合、__add__()などのリフレクトされていないメソッドが失敗すると、操作全体がサポートされないと想定されます。そのため、リフレクトされたメソッドは呼び出されません。