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

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

3.3。 データ・モデル

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

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

すべてのオブジェクトには、ID、タイプ、および値があります。 オブジェクトの identity は、一度作成されると変更されることはありません。 あなたはそれをメモリ内のオブジェクトのアドレスと考えるかもしれません。 ' is '演算子は、2つのオブジェクトのIDを比較します。 id()関数は、そのIDを表す整数を返します(現在はアドレスとして実装されています)。 オブジェクトのタイプも変更できません。 1 オブジェクトのタイプは、オブジェクトがサポートする操作(「長さはありますか?」など)を決定し、そのタイプのオブジェクトの可能な値も定義します。 type()関数は、オブジェクトの型(オブジェクト自体)を返します。 一部のオブジェクトのは変更される可能性があります。 値が変更される可能性のあるオブジェクトは、可変と呼ばれます。 作成後に値が変更できないオブジェクトは、 immutable と呼ばれます。 (可変オブジェクトへの参照を含む不変コンテナオブジェクトの値は、後者の値が変更されると変更される可能性がありますが、コンテナに含まれるオブジェクトのコレクションは変更できないため、コンテナは引き続き不変と見なされます。 したがって、不変性は、変更できない値を持つことと厳密には同じではなく、より微妙です。)オブジェクトの可変性は、そのタイプによって決定されます。 たとえば、数字、文字列、タプルは不変ですが、辞書とリストは変更可能です。

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

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

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

一部のオブジェクトには、他のオブジェクトへの参照が含まれています。 これらはコンテナと呼ばれます。 コンテナの例は、タプル、リスト、辞書です。 参照はコンテナの値の一部です。 ほとんどの場合、コンテナの値について話すときは、含まれているオブジェクトの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の数値はもちろん数学の数値と強く関連していますが、コンピューターでの数値表現の制限があります。

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

numbers.Integral

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

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

プレーン整数

これらは、-2147483648から2147483647の範囲の数値を表します。 (自然ワードサイズが大きいマシンでは範囲が大きくなる可能性がありますが、小さくはなりません。)演算の結果がこの範囲外になると、通常、結果は長整数として返されます(場合によっては例外[X232X ] が代わりに発生します)。 シフトおよびマスク演算の目的で、整数は、32ビット以上を使用し、ユーザーからビットを隠さない2の補数表記を持つと想定されます(つまり、4294967296の異なるビットパターンはすべて異なる値に対応します)。

長整数

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

ブール値

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

整数表現の規則は、負の整数を含むシフトおよびマスク演算の最も意味のある解釈を提供し、プレーン整数ドメインと長整数ドメインを切り替える際の驚きを最小限に抑えることを目的としています。 プレーン整数ドメインで結果が得られる場合、または混合オペランドを使用する場合、どの演算でも長整数ドメインで同じ結果が得られます。 ドメイン間の切り替えは、プログラマーには透過的です。

numbers.Realfloat

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

numbers.Complex

これらは、複素数をマシンレベルの倍精度浮動小数点数のペアとして表します。 浮動小数点数の場合と同じ警告が適用されます。 複素数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

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

不変のシーケンス

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

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

文字列

文字列の項目は文字です。 個別の文字タイプはありません。 文字は1つのアイテムの文字列で表されます。 文字は(少なくとも)8ビットバイトを表します。 組み込み関数 chr()および ord()は、文字とバイト値を表す非負の整数の間で変換します。 値が0〜127のバイトは通常、対応するASCII値を表しますが、値の解釈はプログラム次第です。 文字列データ型は、バイトの配列を表すためにも使用されます。たとえば、ファイルから読み取られたデータを保持するために使用されます。

(ネイティブ文字セットがASCIIでないシステムでは、関数 chr()および ord()がASCIIとEBCDICの間のマッピングを実装する場合、文字列は内部表現でEBCDICを使用できます。文字列の比較では、ASCIIの順序が保持されます。 または、おそらく誰かがより良いルールを提案することができますか?)

Unicode

Unicodeオブジェクトの項目はUnicodeコードユニットです。 Unicodeコードユニットは、1つのアイテムのUnicodeオブジェクトで表され、Unicodeの順序を表す16ビットまたは32ビットの値を保持できます(順序の最大値はsys.maxunicodeで指定され、コンパイル時にPythonがどのように構成されているか)。 サロゲートペアはUnicodeオブジェクトに存在する可能性があり、2つの別個のアイテムとして報告されます。 組み込み関数 unichr()および ord()は、Unicode Standard3.0で定義されているUnicode序数を表すコード単位と非負整数の間で変換します。 他のエンコーディングとの間の変換は、Unicodeメソッドencode()および組み込み関数 unicode()を介して可能です。

タプル

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

可変シーケンス

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

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

リスト

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

バイト配列

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

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

タイプを設定する

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

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

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

セット

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

冷凍セット

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

マッピング

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

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

辞書

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

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

拡張モジュール dbmgdbm 、および bsddb は、マッピングタイプの追加の例を提供します。

呼び出し可能なタイプ

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

ユーザー定義関数

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

特別な属性:

属性

意味

__doc__ func_doc

関数のドキュメント文字列、または使用できない場合はNone

書き込み可能

__name__ func_name

関数の名前

書き込み可能

__module__

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

書き込み可能

__defaults__ func_defaults

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

書き込み可能

__code__ func_code

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

書き込み可能

__globals__ func_globals

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

読み取り専用

__dict__ func_dict

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

書き込み可能

__closure__ func_closure

Noneまたは関数の自由変数のバインディングを含むセルのタプル。

読み取り専用

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

バージョン2.4で変更: func_nameが書き込み可能になりました。

バージョン2.6で変更:二重アンダースコア属性__closure____code____defaults__、および__globals__がエイリアスとして導入されました。 Python3との上位互換性のための対応するfunc_*属性。

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

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

ユーザー定義のメソッド

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

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

バージョン2.2で変更: im_selfは、メソッドを定義したクラスを参照するために使用されていました。

バージョン2.6で変更: Python 3の上位互換性のために、im_func__func__として、im_self__self__としても利用できます。

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

ユーザー定義メソッドオブジェクトは、その属性がユーザー定義関数オブジェクト、バインドされていないユーザー定義メソッドオブジェクト、またはクラスメソッドオブジェクトである場合、クラスの属性を取得するときに(おそらく、そのクラスのインスタンスを介して)作成できます。 属性がユーザー定義のメソッドオブジェクトである場合、新しいメソッドオブジェクトは、それが取得されるクラスが元のメソッドオブジェクトに格納されているクラスと同じであるか、その派生クラスである場合にのみ作成されます。 それ以外の場合は、元のメソッドオブジェクトがそのまま使用されます。

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

クラスまたはインスタンスから別のメソッドオブジェクトを取得してユーザー定義のメソッドオブジェクトを作成する場合、新しいインスタンスのim_func属性が元のメソッドではないことを除いて、動作は関数オブジェクトの場合と同じです。オブジェクトですが、そのim_func属性です。

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

バインドされていないユーザー定義メソッドオブジェクトが呼び出されると、基になる関数(im_func)が呼び出されますが、最初の引数は適切なクラス(im_class)またはその派生クラス。

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

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

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

ジェネレーター機能

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

組み込み関数

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

組み込みメソッド

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

クラスタイプ

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

クラシッククラス

クラスオブジェクトについては、以下で説明します。 クラスオブジェクトが呼び出されると、新しいクラスインスタンス(以下でも説明)が作成されて返されます。 これは、クラスの__init__()メソッドがあれば、それを呼び出すことを意味します。 引数はすべて__init__()メソッドに渡されます。 __init__()メソッドがない場合は、引数なしでクラスを呼び出す必要があります。

クラスインスタンス

クラスインスタンスについて以下に説明します。 クラスインスタンスは、クラスに__call__()メソッドがある場合にのみ呼び出すことができます。 x(arguments)は、x.__call__(arguments)の省略形です。

モジュール

モジュールは、 import ステートメントによってインポートされます(セクション importステートメントを参照)。 モジュールオブジェクトには、ディクショナリオブジェクトによって実装された名前空間があります(これは、モジュールで定義された関数のfunc_globals属性によって参照されるディクショナリです)。 属性参照は、このディクショナリのルックアップに変換されます。たとえば、m.xm.__dict__["x"]と同等です。 モジュールオブジェクトには、モジュールの初期化に使用されるコードオブジェクトが含まれていません(初期化が完了すると必要ないため)。

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

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

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

クラス

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

クラス属性参照(たとえば、クラスCの場合)が、関連するクラスがCまたはその基本クラスの1つであるユーザー定義関数オブジェクトまたはバインドされていないユーザー定義メソッドオブジェクトを生成する場合、im_class属性がCであるバインドされていないユーザー定義のメソッドオブジェクトに変換されます。 クラスメソッドオブジェクトを生成する場合、im_self属性がCであるバインドされたユーザー定義メソッドオブジェクトに変換されます。 静的メソッドオブジェクトを生成する場合、静的メソッドオブジェクトによってラップされたオブジェクトに変換されます。 クラスから取得した属性が __ dict __ に実際に含まれている属性と異なる可能性がある別の方法については、セクション記述子の実装を参照してください(新しいスタイルのクラスのみが記述子をサポートすることに注意してください)。

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

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

特別な属性: __ name __ はクラス名です。 __module__は、クラスが定義されたモジュール名です。 __ dict __ は、クラスの名前空間を含む辞書です。 __ bases __ は、基本クラスリストに出現する順序で基本クラスを含むタプル(空またはシングルトンの可能性があります)です。 __doc__はクラスのドキュメント文字列であり、未定義の場合はNoneです。

クラスインスタンス

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

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

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

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

ファイル

ファイルオブジェクトは、開いているファイルを表します。 ファイルオブジェクトは、 open()組み込み関数、および os.popen()os.fdopen()、および[ X130X] ソケットオブジェクトのメソッド(およびおそらく他の関数または拡張モジュールによって提供されるメソッドによる)。 オブジェクトsys.stdinsys.stdout、およびsys.stderrは、インタープリターの標準の入力、出力、およびエラーストリームに対応するファイルオブジェクトに初期化されます。 ファイルオブジェクトの完全なドキュメントについては、ファイルオブジェクトを参照してください。

内部タイプ

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

コードオブジェクト

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

特別な読み取り専用属性:co_nameは関数名を示します。 co_argcountは、位置引数(デフォルト値の引数を含む)の数です。 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_restrictedは、関数が制限付き実行モードで実行されているかどうかを示すフラグです。 f_lastiは正確な指示を与えます(これはコードオブジェクトのバイトコード文字列へのインデックスです)。

特別な書き込み可能な属性:f_traceは、Noneでない場合、各ソースコード行の先頭で呼び出される関数です(これはデバッガーによって使用されます)。 f_exc_typef_exc_valuef_exc_tracebackは、現在のフレームで別の例外が発生した場合に、親フレームで発生した最後の例外を表します(他のすべての場合は [ X334X]); f_linenoは、フレームの現在の行番号です。トレース関数内からこれに書き込むと、指定された行にジャンプします(最下部のフレームのみ)。 デバッガーは、f_linenoに書き込むことにより、Jumpコマンド(別名Set Next Statement)を実装できます。

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

トレースバックオブジェクトは、例外のスタックトレースを表します。 例外が発生すると、トレースバックオブジェクトが作成されます。 例外ハンドラーの検索によって実行スタックが巻き戻されると、巻き戻された各レベルで、トレースバックオブジェクトが現在のトレースバックの前に挿入されます。 例外ハンドラーが入力されると、スタックトレースがプログラムで使用できるようになります。 (セクション tryステートメントを参照してください。)sys.exc_tracebackとして、またsys.exc_info()によって返されるタプルの3番目の項目としてアクセスできます。 後者は、プログラムが複数のスレッドを使用しているときに正しく機能するため、推奨されるインターフェースです。 プログラムに適切なハンドラーが含まれていない場合、スタックトレースは標準エラーストリームに書き込まれます(適切にフォーマットされます)。 インタプリタがインタラクティブな場合は、sys.last_tracebackとしてユーザーが利用できるようになります。

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

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

拡張スライス構文が使用されている場合、スライスオブジェクトはスライスを表すために使用されます。 これは、a[i:j:step]a[i:j, k:l]a[..., i:j]のように、2つのコロン、またはコンマで区切られた複数のスライスまたは省略記号を使用したスライスです。 組み込みの slice()関数によっても作成されます。

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

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

slice.indices(self, length)

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

バージョン2.3の新機能。

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

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

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

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


3.3。 新しいスタイルとクラシックなクラス

クラスとインスタンスには、古いスタイル(またはクラシック)と新しいスタイルの2つのフレーバーがあります。

Python 2.1までは、classの概念はtypeの概念とは無関係であり、使用可能なフレーバーは古いスタイルのクラスだけでした。 古いスタイルのクラスの場合、ステートメントx.__class__x のクラスを提供しますが、type(x)は常に<type 'instance'>です。 これは、クラスに関係なく、すべての古いスタイルのインスタンスがinstanceと呼ばれる単一の組み込み型で実装されているという事実を反映しています。

classtypeの概念を統一するために、Python2.2で新しいスタイルのクラスが導入されました。 新しいスタイルのクラスは、単なるユーザー定義型であり、それ以上でもそれ以下でもありません。 x が新しいスタイルのクラスのインスタンスである場合、type(x)は通常x.__class__と同じです(これは保証されていませんが、新しいスタイルのクラスインスタンスはx.__class__に対して返される値をオーバーライドすることが許可されています。

新しいスタイルのクラスを導入する主な動機は、完全なメタモデルを備えた統合オブジェクトモデルを提供することです。 また、ほとんどの組み込み型をサブクラス化する機能や、計算されたプロパティを有効にする「記述子」の導入など、多くの実用的な利点があります。

互換性の理由から、クラスはデフォルトでも古いスタイルのままです。 新しいスタイルのクラスは、別の新しいスタイルのクラスを指定することによって作成されます(つまり、 タイプ)を親クラスとして、または他の親が必要ない場合は「トップレベルタイプ」オブジェクト。 新しいスタイルのクラスの動作は、 type()が返すものに加えて、いくつかの重要な詳細において古いスタイルのクラスの動作とは異なります。 これらの変更のいくつかは、特別なメソッドが呼び出される方法のように、新しいオブジェクトモデルの基本です。 その他は、多重継承の場合のメソッド解決順序など、互換性の懸念のために以前は実装できなかった「修正」です。

このマニュアルは、Pythonのクラスの仕組みを包括的にカバーすることを目的としていますが、新しいスタイルのクラスのカバーに関しては、まだ一部の領域で不足している可能性があります。 追加情報のソースについては、 https://www.python.org/doc/newstyle/を参照してください。

古いスタイルのクラスはPython3で削除され、新しいスタイルのクラスのみが残ります。


3.4。 特別なメソッド名

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

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

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

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

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

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

__ new __()cls のインスタンスを返す場合、新しいインスタンスの __ init __()メソッドは__init__(self[, ...])のように呼び出されます。ここで、[X148X ] self は新しいインスタンスであり、残りの引数は __ new __()に渡されたものと同じです。

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

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

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

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

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

object.__del__(self)

インスタンスが破棄されようとしているときに呼び出されます。 これはデストラクタとも呼ばれます。 基本クラスに __ del __()メソッドがある場合、派生クラスの __ del __()メソッドがある場合は、インスタンスの基本クラス部分が適切に削除されるように、明示的に呼び出す必要があります。 。 __ del __()メソッドは、インスタンスへの新しい参照を作成することにより、インスタンスの破棄を延期することが可能であることに注意してください(推奨されていません!)。 その後、この新しい参照が削除されたときに呼び出される場合があります。 __ del __()メソッドが、インタープリターの終了時にまだ存在するオブジェクトに対して呼び出されることは保証されていません。

ノート

del xx.__del__()を直接呼び出しません—前者はxの参照カウントを1つ減らし、後者はxの参照の場合にのみ呼び出されますカウントがゼロになります。 オブジェクトの参照カウントがゼロになるのを妨げる可能性のある一般的な状況には、次のものがあります。オブジェクト間の循環参照(たとえば、二重リンクリストまたは親ポインターと子ポインターを持つツリーデータ構造)。 例外をキャッチした関数のスタックフレーム上のオブジェクトへの参照(sys.exc_tracebackに格納されているトレースバックはスタックフレームを存続させます)。 または、インタラクティブモードで未処理の例外を発生させたスタックフレーム上のオブジェクトへの参照(sys.last_tracebackに格納されたトレースバックはスタックフレームを存続させます)。 最初の状況は、サイクルを明示的に中断することによってのみ修正できます。 後者の2つの状況は、Nonesys.exc_tracebackまたはsys.last_tracebackに格納することで解決できます。 ガベージである循環参照は、オプションサイクル検出器が有効になっている場合(デフォルトでオン)に検出されますが、Pythonレベルの __ del __()メソッドが含まれていない場合にのみクリーンアップできます。 __ del __()メソッドがサイクル検出器によってどのように処理されるか、特にgarbage値の説明については、 gc モジュールのドキュメントを参照してください。

警告

__ del __()メソッドが呼び出されるという不安定な状況のため、実行中に発生した例外は無視され、代わりにsys.stderrに警告が出力されます。 また、モジュールの削除に応答して __ del __()が呼び出された場合(たとえば、プログラムの実行が完了した場合)、 __ del __()メソッドによって参照される他のグローバルがすでに呼び出されている可能性があります。削除されたか、取り壊される過程にあります(例: 輸入機械の停止)。 このため、 __ del __()メソッドは、外部不変条件を維持するために必要な絶対最小値を実行する必要があります。 バージョン1.5以降、Pythonは、名前が1つのアンダースコアで始まるグローバルが、他のグローバルが削除される前にモジュールから削除されることを保証します。 そのようなグローバルへの他の参照が存在しない場合、これは、 __ del __()メソッドが呼び出されたときにインポートされたモジュールが引き続き使用可能であることを保証するのに役立つ場合があります。

-R コマンドラインオプションも参照してください。

object.__repr__(self)

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

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

object.__str__(self)
str()組み込み関数および print ステートメントによって呼び出され、オブジェクトの「非公式」文字列表現を計算します。 これは、有効なPython式である必要がないという点で、 __ repr __()とは異なります。代わりに、より便利で簡潔な表現を使用できます。 戻り値は文字列オブジェクトである必要があります。
object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)

バージョン2.1の新機能。

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

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

比較演算子間に暗黙の関係はありません。 x==yの真実は、x!=yが偽であることを意味するものではありません。 したがって、 __ eq __()を定義するときは、演算子が期待どおりに動作するように __ ne __()も定義する必要があります。 カスタム比較操作をサポートし、辞書キーとして使用できる hashable オブジェクトの作成に関する重要な注意事項については、 __ hash __()の段落を参照してください。

これらのメソッドのスワップ引数バージョンはありません(左の引数が操作をサポートしていないが、右の引数はサポートしている場合に使用されます)。 むしろ、 __ lt __()__ gt __()はお互いの反射であり、 __ le __()__ ge __()はお互いの反射です。 __ eq __()__ ne __()はそれぞれ独自の反射です。

豊富な比較方法への議論は決して強制されません。

単一のルート操作から順序付け操作を自動的に生成するには、 functools.total_ordering()を参照してください。

object.__cmp__(self, other)
リッチ比較(上記を参照)が定義されていない場合、比較操作によって呼び出されます。 self < otherの場合は負の整数、self == otherの場合はゼロ、self > otherの場合は正の整数を返す必要があります。 __ cmp __()__ eq __()または __ ne __()操作が定義されていない場合、クラスインスタンスはオブジェクトID(「アドレス」)によって比較されます。 カスタム比較操作をサポートし、辞書キーとして使用できる hashable オブジェクトの作成に関する重要な注意事項については、 __ hash __()の説明も参照してください。 (注:Python 1.5以降、 __ cmp __()によって例外が伝播されないという制限が削除されました。)
object.__rcmp__(self, other)

バージョン2.1で変更:サポートされなくなりました。

object.__hash__(self)

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

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

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

ユーザー定義クラスには、デフォルトで __ cmp __()および __ hash __()メソッドがあります。 それらを使用すると、すべてのオブジェクトが等しくなく(それ自体を除く)比較され、x.__hash__()id(x)から派生した結果を返します。

親クラスから __ hash __()メソッドを継承するが、 __ cmp __()または __ eq __()の意味を変更して、返されるハッシュ値がより適切なもの(例: デフォルトのIDベースの同等性ではなく、値ベースの同等性の概念に切り替えることにより、クラス定義で__hash__ = Noneを設定することにより、ハッシュ不可として明示的にフラグを立てることができます。 そうすることは、プログラムがハッシュ値を取得しようとしたときにクラスのインスタンスが適切なTypeErrorを発生させるだけでなく、isinstance(obj, collections.Hashable)をチェックするときに(クラスとは異なり)ハッシュ不可能として正しく識別されることを意味します。独自の __ hash __()を定義して、TypeErrorを明示的に発生させます。

バージョン2.5での変更: __ hash __()も長整数オブジェクトを返す可能性があります。 次に、32ビット整数がそのオブジェクトのハッシュから導出されます。

バージョン2.6での変更: __ hash __None に設定して、クラスのインスタンスにハッシュ不可として明示的にフラグを立てることができるようになりました。

object.__nonzero__(self)
真理値テストと組み込み操作bool()を実装するために呼び出されます。 FalseまたはTrue、またはそれらに相当する整数0または1を返す必要があります。 このメソッドが定義されていない場合、 __ len __()が定義されている場合は呼び出され、結果がゼロ以外の場合はオブジェクトはtrueと見なされます。 クラスが __ len __()__ nonzero __()も定義していない場合、そのすべてのインスタンスはtrueと見なされます。
object.__unicode__(self)
unicode()組み込みを実装するために呼び出されます。 Unicodeオブジェクトを返す必要があります。 このメソッドが定義されていない場合、文字列変換が試行され、文字列変換の結果は、システムのデフォルトエンコーディングを使用してUnicodeに変換されます。


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

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

object.__getattr__(self, name)

属性ルックアップが通常の場所で属性を見つけられなかった場合に呼び出されます(つまり、 これはインスタンス属性ではなく、selfのクラスツリーにもありません。 nameは属性名です。 このメソッドは、(計算された)属性値を返すか、AttributeError例外を発生させる必要があります。

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

object.__setattr__(self, name, value)

属性の割り当てが試行されたときに呼び出されます。 これは通常のメカニズムの代わりに呼び出されます(つまり 値をインスタンスディクショナリに格納します)。 name は属性名、 value はそれに割り当てられる値です。

__ setattr __()がインスタンス属性に割り当てたい場合は、単にself.name = valueを実行するべきではありません。これにより、それ自体が再帰的に呼び出されます。 代わりに、インスタンス属性のディクショナリに値を挿入する必要があります(例:self.__dict__[name] = value)。 新しいスタイルのクラスの場合、インスタンスディクショナリにアクセスするのではなく、object.__setattr__(self, name, value)などの同じ名前の基本クラスメソッドを呼び出す必要があります。

object.__delattr__(self, name)
__ setattr __()と同様ですが、割り当てではなく属性を削除します。 これは、del obj.nameがオブジェクトにとって意味がある場合にのみ実装する必要があります。

3.4.2.1。 新しいスタイルのクラスへのより多くの属性アクセス

次のメソッドは、新しいスタイルのクラスにのみ適用されます。

object.__getattribute__(self, name)

クラスのインスタンスの属性アクセスを実装するために無条件に呼び出されます。 クラスが __ getattr __()も定義している場合、 __ getattribute __()が明示的に呼び出すか、AttributeErrorを発生させない限り、後者は呼び出されません。 このメソッドは、(計算された)属性値を返すか、AttributeError例外を発生させる必要があります。 このメソッドでの無限再帰を回避するために、その実装では常に同じ名前の基本クラスメソッドを呼び出して、必要な属性(object.__getattribute__(self, name)など)にアクセスする必要があります。

ノート

このメソッドは、言語構文または組み込み関数を介した暗黙的な呼び出しの結果として、特別なメソッドを検索するときにバイパスされる可能性があります。 新しいスタイルのクラスの特別なメソッドルックアップを参照してください。


3.4.2.2。 記述子の実装

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

object.__get__(self, instance, owner)
所有者クラスの属性(クラス属性アクセス)またはそのクラスのインスタンスの属性(インスタンス属性アクセス)を取得するために呼び出されます。 owner は常に所有者クラスですが、 instance は属性がアクセスされたインスタンスであり、Noneは属性が owner [を介してアクセスされた場合です。 X188X]。 このメソッドは、(計算された)属性値を返すか、AttributeError例外を発生させる必要があります。
object.__set__(self, instance, value)
所有者クラスのインスタンスインスタンスの属性を新しい値に設定するために呼び出されます。
object.__delete__(self, instance)
所有者クラスのインスタンスインスタンスの属性を削除するために呼び出されます。


3.4.2.3。 記述子の呼び出し

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

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

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

記述子呼び出しの開始点は、バインディング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.4.2.4。 __slots__

デフォルトでは、古いスタイルと新しいスタイルの両方のクラスのインスタンスには、属性ストレージ用のディクショナリがあります。 これにより、インスタンス変数が非常に少ないオブジェクトのスペースが無駄になります。 多数のインスタンスを作成すると、スペースの消費が急激になる可能性があります。

新しいスタイルのクラス定義で __ slots __ を定義することにより、デフォルトをオーバーライドできます。 __ slots __ 宣言は、インスタンス変数のシーケンスを取り、各変数の値を保持するのに十分なスペースを各インスタンスに予約します。 インスタンスごとに __ dict __ が作成されないため、スペースが節約されます。

__slots__

このクラス変数には、インスタンスで使用される変数名を持つ文字列、反復可能、または文字列のシーケンスを割り当てることができます。 新しいスタイルのクラスで定義されている場合、 __ slots __ は宣言された変数用のスペースを予約し、インスタンスごとに __ dict ____ weakref __ が自動的に作成されないようにします。

バージョン2.2の新機能。

__ slots __ の使用に関する注意事項

  • __ slots __ のないクラスから継承する場合、そのクラスの __ dict __ 属性は常にアクセス可能であるため、サブクラスの __ slots __ 定義は無意味です。

  • __ dict __ 変数がないと、 __ slots __ 定義にリストされていない新しい変数をインスタンスに割り当てることはできません。 リストされていない変数名に割り当てようとすると、AttributeErrorが発生します。 新しい変数の動的な割り当てが必要な場合は、 __ slots __ 宣言の文字列のシーケンスに'__dict__'を追加します。

    バージョン2.3で変更:以前は、 __ slots __ 宣言に'__dict__'を追加しても、インスタンス変数名のシーケンスに具体的にリストされていない新しい属性を割り当てることができませんでした。

  • 各インスタンスに __ weakref __ 変数がない場合、 __ slots __ を定義するクラスはそのインスタンスへの弱参照をサポートしません。 弱参照のサポートが必要な場合は、 __ slot __ 宣言の文字列のシーケンスに'__weakref__'を追加します。

    バージョン2.3で変更:以前は、'__weakref__'__ slot __ 宣言に追加しても、弱参照のサポートが有効になりませんでした。

  • __ slots __ は、変数名ごとに記述子( Implementation Descriptors )を作成することにより、クラスレベルで実装されます。 その結果、クラス属性を使用して、 __ slots __ で定義されたインスタンス変数のデフォルト値を設定することはできません。 そうしないと、クラス属性が記述子の割り当てを上書きします。

  • __ slots __ 宣言のアクションは、それが定義されているクラスに限定されます。 その結果、サブクラスは __ slot __追加のスロットの名前のみを含む必要があります)も定義しない限り、 __ dict __ を持ちます。

  • クラスが基本クラスでも定義されているスロットを定義している場合、基本クラススロットで定義されているインスタンス変数にアクセスできません(基本クラスから直接記述子を取得する場合を除く)。 これにより、プログラムの意味が未定義になります。 将来的には、これを防ぐためにチェックが追加される可能性があります。

  • 空でない __ slots __ は、 longstrtuple などの「可変長」組み込み型から派生したクラスでは機能しません。

  • 文字列以外の反復可能オブジェクトは、 __ slots __ に割り当てることができます。 マッピングも使用できます。 ただし、将来的には、各キーに対応する値に特別な意味が割り当てられる可能性があります。

  • __ class __ の割り当ては、両方のクラスが同じ __ slot __ を持っている場合にのみ機能します。

    バージョン2.6で変更:以前は、 __ class __ の割り当てで、新しいクラスまたは古いクラスのいずれかに __ slot __ がある場合にエラーが発生していました。


3.4.3。 クラス作成のカスタマイズ

デフォルトでは、新しいスタイルのクラスは type()を使用して構築されます。 クラス定義は別の名前空間に読み込まれ、クラス名の値はtype(name, bases, dict)の結果にバインドされます。

クラス定義が読み取られるときに、 __ metaclass __ が定義されている場合、 type()の代わりにそれに割り当てられた呼び出し可能オブジェクトが呼び出されます。 これにより、クラス作成プロセスを監視または変更するクラスまたは関数を作成できます。

  • クラスが作成される前にクラスディクショナリを変更する。
  • 別のクラスのインスタンスを返す–基本的にファクトリ関数の役割を実行します。

これらの手順は、メタクラスの__new__()メソッドで実行する必要があります。このメソッドからtype.__new__()を呼び出して、さまざまなプロパティを持つクラスを作成できます。 この例では、クラスを作成する前に、クラスディクショナリに新しい要素を追加します。

class metacls(type):
    def __new__(mcs, name, bases, dict):
        dict['foo'] = 'metacls was here'
        return type.__new__(mcs, name, bases, dict)

もちろん、他のクラスメソッドをオーバーライドする(または新しいメソッドを追加する)こともできます。 たとえば、メタクラスでカスタム__call__()メソッドを定義すると、クラスが呼び出されたときのカスタム動作が可能になります。 常に新しいインスタンスを作成するとは限りません。

__metaclass__

この変数は、namebases、およびdictの呼び出し可能な受け入れ引数にすることができます。 クラスの作成時に、組み込みの type()の代わりにcallableが使用されます。

バージョン2.2の新機能。

適切なメタクラスは、次の優先順位ルールによって決定されます。

  • dict['__metaclass__']が存在する場合は、それが使用されます。
  • それ以外の場合、少なくとも1つの基本クラスがある場合は、そのメタクラスが使用されます(これにより、最初に __ class __ 属性が検索され、見つからない場合はそのタイプが使用されます)。
  • それ以外の場合、__ metaclass__という名前のグローバル変数が存在する場合は、それが使用されます。
  • それ以外の場合は、古いスタイルのクラシックメタクラス(types.ClassType)が使用されます。

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


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

バージョン2.6の新機能。


次のメソッドは、 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.4.5。 呼び出し可能なオブジェクトのエミュレート

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


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

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

object.__len__(self)
組み込み関数 len()を実装するために呼び出されます。 オブジェクトの長さ、整数>= 0を返す必要があります。 また、 __ nonzero __()メソッドを定義せず、 __ len __()メソッドがゼロを返すオブジェクトは、ブールコンテキストではfalseと見なされます。
object.__getitem__(self, key)

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

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

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

object.__reversed__(self)

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

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

バージョン2.6の新機能。

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

object.__contains__(self, item)

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

__ contains __()を定義しないオブジェクトの場合、メンバーシップテストは最初に __ iter __()を介して反復を試行し、次に __ getitem __()を介して古いシーケンス反復プロトコルを試行します。 、言語リファレンスこのセクションを参照してください。


3.4.7。 シーケンスタイプをエミュレーションするための追加の方法

次のオプションのメソッドを定義して、シーケンスオブジェクトをさらにエミュレートできます。 不変シーケンスメソッドは、せいぜい__getslice__()のみを定義する必要があります。 可変シーケンスは、3つのメソッドすべてを定義する場合があります。

object.__getslice__(self, i, j)

バージョン2.0以降非推奨:スライスオブジェクトを __ getitem __()メソッドのパラメーターとしてサポートします。 (ただし、CPythonの組み込み型は、現在も __ getslice __()を実装しています。 したがって、スライスを実装するときは、派生クラスでオーバーライドする必要があります。)

self[i:j]の評価を実装するために呼び出されます。 返されるオブジェクトは、 self と同じタイプである必要があります。 スライス式で欠落している i または j は、それぞれゼロまたは sys.maxsize に置き換えられることに注意してください。 スライスで負のインデックスが使用されている場合、シーケンスの長さがそのインデックスに追加されます。 インスタンスが __ len __()メソッドを実装していない場合、AttributeErrorが発生します。 この方法で調整されたインデックスがまだマイナスでないという保証はありません。 シーケンスの長さより大きいインデックスは変更されません。 __ getslice __()が見つからない場合は、代わりにスライスオブジェクトが作成され、代わりに __ getitem __()に渡されます。

object.__setslice__(self, i, j, sequence)

self[i:j]への割り当てを実装するために呼び出されます。 ij については、 __ getslice __()と同じ注意事項です。

このメソッドは非推奨です。 __ setslice __()が見つからない場合、またはself[i:j:k]形式の拡張スライスの場合、スライスオブジェクトが作成され、 __ setitem __()ではなく __ setitem __()に渡されます。 X163X] __ setslice __()が呼び出されています。

object.__delslice__(self, i, j)
self[i:j]の削除を実装するために呼び出されます。 ij については、 __ getslice __()と同じ注意事項です。 このメソッドは非推奨です。 __ delslice __()が見つからない場合、またはself[i:j:k]形式の拡張スライスの場合、スライスオブジェクトが作成され、 __ delitem __()ではなく __ delitem __()に渡されます。 X163X] __ delslice __()が呼び出されています。

これらのメソッドは、単一のコロンを持つ単一のスライスが使用され、sliceメソッドが使用可能な場合にのみ呼び出されることに注意してください。 拡張スライス表記を含むスライス操作の場合、またはスライスメソッドがない場合、__getitem__()__setitem__()、または__delitem__()は、引数としてスライスオブジェクトを使用して呼び出されます。

次の例は、プログラムまたはモジュールを以前のバージョンのPythonと互換性を持たせる方法を示しています(メソッド__getitem__()__setitem__()、および__delitem__()が引数としてスライスオブジェクトをサポートしていると仮定)。

class MyClass:
    ...
    def __getitem__(self, index):
        ...
    def __setitem__(self, index, value):
        ...
    def __delitem__(self, index):
        ...

    if sys.version_info < (2, 0):
        # They won't be defined if version is at least 2.0 final

        def __getslice__(self, i, j):
            return self[max(0, i):max(0, j):]
        def __setslice__(self, i, j, seq):
            self[max(0, i):max(0, j):] = seq
        def __delslice__(self, i, j):
            del self[max(0, i):max(0, j):]
    ...

max()の呼び出しに注意してください。 これらは、__*slice__()メソッドが呼び出される前に負のインデックスを処理するために必要です。 負のインデックスが使用される場合、__*item__()メソッドは提供されたとおりにそれらを受け取りますが、__*slice__()メソッドはインデックス値の「調理済み」形式を取得します。 負のインデックス値ごとに、メソッドを呼び出す前にシーケンスの長さがインデックスに追加されます(これでも負のインデックスになる可能性があります)。 これは、組み込みシーケンスタイプによる負のインデックスの通常の処理であり、__*item__()メソッドもこれを行うことが期待されています。 ただし、すでにそれを行っているはずなので、負のインデックスを渡すことはできません。 __*item__()メソッドに渡される前に、シーケンスの境界に制約される必要があります。 max(0, i)を呼び出すと、適切な値が返されます。


3.4.8。 数値型のエミュレート

数値オブジェクトをエミュレートするには、次のメソッドを定義できます。 実装されている特定の種類の数値でサポートされていない演算(たとえば、非整数のビット演算)に対応するメソッドは、未定義のままにしておく必要があります。

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

これらのメソッドの1つが、指定された引数を使用した操作をサポートしていない場合は、NotImplementedを返す必要があります。

object.__div__(self, other)

object.__truediv__(self, other)

除算演算子(/)は、これらのメソッドによって実装されます。 __ truediv __()メソッドは、__future__.divisionが有効な場合に使用され、それ以外の場合は __ div __()が使用されます。 これら2つのメソッドのいずれか1つだけが定義されている場合、オブジェクトは代替コンテキストでの分割をサポートしません。 代わりにTypeErrorが発生します。
object.__radd__(self, other)
object.__rsub__(self, other)
object.__rmul__(self, other)
object.__rdiv__(self, other)
object.__rtruediv__(self, other)
object.__rfloordiv__(self, other)
object.__rmod__(self, other)
object.__rdivmod__(self, other)
object.__rpow__(self, other)
object.__rlshift__(self, other)
object.__rrshift__(self, other)
object.__rand__(self, other)
object.__rxor__(self, other)
object.__ror__(self, other)

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

三元 pow()__ rpow __()を呼び出そうとしないことに注意してください(強制ルールは複雑になりすぎます)。

ノート

右のオペランドの型が左のオペランドの型のサブクラスであり、そのサブクラスが操作の反映されたメソッドを提供する場合、このメソッドは左のオペランドの反映されていないメソッドの前に呼び出されます。 この動作により、サブクラスは祖先の操作をオーバーライドできます。

object.__iadd__(self, other)

object.__isub__(self, other)
object.__imul__(self, other)
object.__idiv__(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]、**=<<=>>=&=^=|=)。 これらのメソッドは、その場で操作を実行し( self を変更)、結果を返す必要があります( self である可能性がありますが、そうである必要はありません)。 特定のメソッドが定義されていない場合、拡張された割り当ては通常のメソッドにフォールバックします。 たとえば、ステートメントx += yを実行するには、 x__ iadd __()メソッドを持つクラスのインスタンスであり、x.__iadd__(y)が呼び出されます。 。 x__ iadd __()メソッドを定義しないクラスのインスタンスである場合、評価と同様に、x.__add__(y)およびy.__radd__(x)が考慮されます。 x + yの。
object.__neg__(self)

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

単項算術演算(-+abs()、および~)を実装するために呼び出されます。
object.__complex__(self)

object.__int__(self)
object.__long__(self)
object.__float__(self)

組み込み関数 complex()int()long()、および float()を実装するために呼び出されます。 適切なタイプの値を返す必要があります。
object.__oct__(self)

object.__hex__(self)

組み込み関数 oct()および hex()を実装するために呼び出されます。 文字列値を返す必要があります。
object.__index__(self)

operator.index()を実装するために呼び出されます。 Pythonが整数オブジェクトを必要とするときはいつでも呼び出されます(スライスなど)。 整数(intまたはlong)を返す必要があります。

バージョン2.5の新機能。

object.__coerce__(self, other)
「混合モード」の数値演算を実装するために呼び出されます。 共通の数値型に変換された selfother を含む2タプルを返すか、変換が不可能な場合はNoneを返す必要があります。 共通の型がotherの型である場合、インタプリタは他のオブジェクトにも強制を試みるように要求するため、Noneを返すだけで十分です(ただし、他のタイプは変更できません。ここで他のタイプに変換すると便利です)。 NotImplementedの戻り値は、Noneを返すのと同じです。


3.4.9。 強制ルール

このセクションは、強制のルールを文書化するために使用されました。 言語が進化するにつれて、強制ルールを正確に文書化することが難しくなりました。 ある特定の実装の1つのバージョンが何をするかを文書化することは望ましくありません。 代わりに、ここに強制に関するいくつかの非公式のガイドラインがあります。 Python 3では、強制はサポートされません。

  • If the left operand of a % operator is a string or Unicode object, no coercion takes place and the string formatting operation is invoked instead.

  • 強制操作を定義することは推奨されなくなりました。 強制を定義しない型の混合モード操作は、元の引数を操作に渡します。

  • 新しいスタイルのクラス(オブジェクトから派生したクラス)は、二項演算子に応答して__coerce__()メソッドを呼び出すことはありません。 __coerce__()が呼び出されるのは、組み込み関数 coerce()が呼び出されたときだけです。

  • ほとんどの目的と目的で、NotImplementedを返す演算子は、まったく実装されていない演算子と同じように扱われます。

  • 以下では、__op__()および__rop__()は、演算子に対応するジェネリックメソッド名を示すために使用されます。 __iop__()は、対応するインプレース演算子に使用されます。 たとえば、演算子 '+'の場合、__add__()__radd__()は二項演算子の左右のバリアントに使用され、__iadd__()はインプレースバリアント。

  • オブジェクト x および y の場合、最初にx.__op__(y)が試行されます。 これが実装されていないか、NotImplementedを返す場合、y.__rop__(x)が試行されます。 これも実装されていないか、NotImplementedを返す場合、TypeError例外が発生します。 ただし、次の例外を参照してください。

  • 前の項目の例外:左側のオペランドが組み込み型または新しいスタイルのクラスのインスタンスであり、右側のオペランドがその型またはクラスの適切なサブクラスのインスタンスであり、ベースの [をオーバーライドする場合X217X]メソッドの場合、右オペランドの__rop__()メソッドが前に左オペランドの__op__()メソッドで試行されます。

    これは、サブクラスが二項演算子を完全にオーバーライドできるようにするために行われます。 それ以外の場合、左側のオペランドの__op__()メソッドは常に右側のオペランドを受け入れます。特定のクラスのインスタンスが予期される場合、そのクラスのサブクラスのインスタンスは常に受け入れられます。

  • いずれかのオペランドタイプが強制を定義する場合、この強制は、そのタイプの__op__()または__rop__()メソッドが呼び出される前に呼び出されますが、すぐには呼び出されません。 強制が呼び出されたオペランドに対して、強制が異なるタイプのオブジェクトを返す場合、プロセスの一部は新しいオブジェクトを使用してやり直されます。

  • インプレース演算子( '+='など)が使用されている場合、左側のオペランドが__iop__()を実装していると、強制なしで呼び出されます。 操作が__op__()および/または__rop__()にフォールバックすると、通常の強制ルールが適用されます。

  • x + yで、 x がシーケンス連結を実装するシーケンスである場合、シーケンス連結が呼び出されます。

  • x * yでは、一方のオペランドがシーケンスの繰り返しを実装するシーケンスで、もう一方のオペランドが整数( int または long )の場合、シーケンスの繰り返しが呼び出されます。

  • 豊富な比較(メソッド__eq__()などによって実装される)は強制を使用しません。 三元比較(__cmp__()によって実装)は、他の二項演算が使用するのと同じ条件下で強制を使用します。

  • 現在の実装では、組み込みの数値型 intlongfloat 、および complex は強制を使用しません。 これらのタイプはすべて、組み込みの coerce()関数で使用するために、__coerce__()メソッドを実装しています。

    バージョン2.7で変更:複合型は、混合型の2進算術演算のために__coerce__()メソッドを暗黙的に呼び出すことはなくなりました。


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

バージョン2.5の新機能。


コンテキストマネージャーは、 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.4.11。 古いスタイルのクラスの特別なメソッドルックアップ

古いスタイルのクラスの場合、特別なメソッドは常に他のメソッドまたは属性とまったく同じ方法で検索されます。 これは、メソッドがx.__getitem__(i)のように明示的に検索されているか、x[i]のように暗黙的に検索されているかに関係なく当てはまります。

この動作は、適切な特殊属性が異なる方法で設定されている場合、特殊なメソッドが単一の古いスタイルのクラスの異なるインスタンスに対して異なる動作を示す可能性があることを意味します。

>>> class C:
...     pass
...
>>> c1 = C()
>>> c2 = C()
>>> c1.__len__ = lambda: 5
>>> c2.__len__ = lambda: 9
>>> len(c1)
5
>>> len(c2)
9

3.4.12。 新しいスタイルのクラスの特別なメソッドルックアップ

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

>>> class C(object):
...     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__()機構をバイパスすると、インタプリタ内で速度を最適化するための大きな範囲が提供されますが、特別なメソッドの処理にある程度の柔軟性があります(特別なメソッドはクラスに設定する必要があります)。インタプリタによって一貫して呼び出されるようにするためのオブジェクト自体)。

脚注

1
特定の制御された条件下で、オブジェクトのタイプを変更できる場合があります。 ただし、正しく処理しないと非常に奇妙な動作を引き起こす可能性があるため、一般的にはお勧めできません。
2
同じタイプのオペランドの場合、リフレクトされていないメソッド(__add__()など)が失敗した場合、操作はサポートされないと想定されます。そのため、リフレクトされたメソッドは呼び出されません。