9. クラス
*********

クラスはデータと機能を組み合わせる方法を提供します。 新規にクラスを作
成することで、新しいオブジェクトの *型* を作成し、その型を持つ新しい *
インスタンス* が作れます。 クラスのそれぞれのインスタンスは自身の状態
を保持する属性を持てます。 クラスのインスタンスは、その状態を変更する
ための (そのクラスが定義する) メソッドも持てます。

Python のクラス機構は、ほかのプログラミング言語に比べて、新しく覚える
構文や規則を最小限に抑えています。 その仕組みは C++ と Modula-3 のクラ
ス機構を組み合わせたものです。 Python のクラスは、オブジェクト指向プロ
グラミングの標準的な機能をすべて備えています。 複数の基底クラスを継承
でき、派生クラスでは基底クラスのどのメソッドもオーバーライドできます。
また、メソッドから基底クラスの同名のメソッドを呼び出せます。 オブジェ
クトに格納するデータの種類や数も自由です。 モジュールと同様に、クラス
も Python の動的な性質を持っています。 クラスは実行時に作られ、作成後
に変更することもできます。

C++ の用語で言うと、クラスメンバはデータメンバも含めて通常 *public* で
す (例外については プライベート変数 を参照してください)。 メンバ関数は
すべて *仮想関数 (virtual)* です。 Modula-3 と同様に、メソッド内からオ
ブジェクトのメンバを参照するための短縮記法はありません。 メソッド関数
の宣言では、オブジェクト自体を表す引数を最初に明示します。 メソッドを
呼び出すと、この引数にオブジェクトが暗黙的に渡されます。 Smalltalk と
同様に、クラス自体もオブジェクトなので、インポートしたり別の名前を付け
たりできます。 C++ や Modula-3 と違って、組み込み型を基底クラスにして
拡張することもできます。 また、C++ と同様に、算術演算子や添字表記など
特別な構文を使う組み込み演算子の多くは、 クラスインスタンスに対する動
作を再定義できます。

(クラスに関して普遍的な用語定義がないので、 Smalltalk と C++ の用語を
場合に応じて使っていくことにします。 C++ よりも Modula-3 の方がオブジ
ェクト指向の意味論が Python に近いので、 Modula-3 の用語を使いたいので
すが、ほとんどの読者は Modula-3 についてしらないでしょうから。)


9.1. 名前とオブジェクトについて
===============================

オブジェクトはそれぞれ固有の存在ですが、同じオブジェクトに複数のスコー
プから複数の名前を束縛できます。 ほかの言語では、これをエイリアス (別
名) と呼びます。 Python を学び始めたばかりでは、この仕組みの重要性は分
かりにくいかもしれません。 数値、文字列、タプルのようなイミュータブル
(変更できない) な基本型を扱うときは、気にしなくても問題ありません。 一
方、リストや辞書など多くの型のミュータブル (変更できる) なオブジェクト
を扱うコードでは、 エイリアスによって意外な動作が起こることがあります
。 エイリアスはいくつかの点でポインタのように振る舞うため、通常はその
性質をプログラムに役立てられます。 例えば、オブジェクトを渡す際に実装
上渡されるのはポインタだけなので、処理の負担は小さくなります。 また、
関数が引数として受け取ったオブジェクトを変更すると、呼び出し側からもそ
の変更が見えます。 このため、Pascal のように引数の渡し方を 2 種類用意
する必要がありません。


9.2. Python のスコープと名前空間
================================

クラスを紹介する前に、Python のスコープの規則について説明する必要があ
ります。 クラス定義は名前空間を巧みに利用するので、その動作を十分に理
解するには、スコープと名前空間の仕組みを知っておく必要があります。 な
お、この知識は高度なプログラミングを行う Python プログラマーなら誰にと
っても役立ちます。

まず定義から始めましょう。

*名前空間 (namespace)* とは、名前からオブジェクトへの対応付け
(mapping) です。ほとんどの名前空間は、現状では Python の辞書として実装
されていますが、そのことは通常は (パフォーマンス以外では) 目立つことは
ないし、将来は変更されるかもしれません。名前空間の例には、組込み名の集
合 ("abs()" 等の関数や組込み例外名)、モジュール内のグローバルな名前、
関数を呼び出したときのローカルな名前があります。オブジェクトの属性から
なる集合もまた、ある意味では名前空間です。名前空間について知っておくべ
き重要なことは、異なった名前空間にある名前の間には全く関係がないという
ことです。例えば、二つの別々のモジュールの両方で関数 "maximize" という
関数を定義することができ、定義自体は混同されることはありません --- モ
ジュールのユーザは名前の前にモジュール名をつけなければなりません。

ところで、 *属性* という言葉は、ドットに続く名前すべてに対して使ってい
ます --- 例えば式 "z.real" で、 "real" はオブジェクト "z" の属性です。
厳密にいえば、モジュール内の名前に対する参照は属性の参照です。式
"modname.funcname" では、 "modname" はあるモジュールオブジェクトで、
"funcname" はその属性です。この場合には、モジュールの属性とモジュール
の中で定義されているグローバル名の間には、直接的な対応付けがされます。
これらの名前は同じ名前空間を共有しているのです！ [1]

属性は読取り専用にも、書込み可能にもできます。書込み可能であれば、属性
に代入することができます。モジュール属性は書込み可能で、
"modname.the_answer = 42" と書くことができます。書込み可能な属性は、
"del" 文で削除することもできます。例えば、 "del modname.the_answer" は
、 "modname" で指定されたオブジェクトから属性 "the_answer" を除去しま
す。

名前空間は様々な時点で作成され、その寿命も様々です。組み込みの名前が入
った名前空間は Python インタプリタが起動するときに作成され、決して削除
されることはありません。モジュールのグローバルな名前空間は、モジュール
定義が読み込まれたときに作成されます。通常、モジュールの名前空間は、イ
ンタプリタが終了するまで残ります。インタプリタのトップレベルで実行され
た文は、スクリプトファイルから読み出されたものでも対話的に読み出された
ものでも、 "__main__" という名前のモジュールの一部分であるとみなされる
ので、独自の名前空間を持つことになります。 (組み込みの名前は実際にはモ
ジュール内に存在します。そのモジュールは "builtins" と呼ばれています。
)

関数のローカルな名前空間は、関数が呼び出されたときに作成され、関数から
戻ったときや、関数内で例外が送出され、かつ関数内で処理されなかった場合
に削除されます。 (実際には、忘れられる、と言ったほうが起きていることを
よく表しています。) もちろん、再帰呼出しのときには、各々の呼び出しで各
自のローカルな名前空間があります。

*スコープ (scope)* とは、ある名前空間が直接アクセスできるような、
Python プログラムのテキスト上の領域です。 "直接アクセス可能" とは、修
飾なしに (訳注: "spam.egg" ではなく単に "egg" のように) 名前を参照した
際に、その名前空間から名前を見つけようと試みることを意味します。

スコープは静的に決定されますが、動的に使用されます。実行中はいつでも、
直接名前空間にアクセス可能な、3つまたは4つの入れ子になったスコープがあ
ります:

* 最初に探される、最も内側のスコープは、ローカルな名前を持っています。

* 外側の(enclosing)関数のスコープは、近いほうから順に探され、ローカル
  でもグローバルでもない名前を持っています。

* 最後から 2 番目のスコープは現在のモジュールのグローバルな名前を持っ
  ています。

* 一番外側の(最後に検索される)スコープはビルトイン名を持っています。

名前を global と宣言すると、その名前への参照と代入はすべて、モジュール
のグローバル名を持つ最後から 2 番目のスコープで直接行われます。 最も内
側のスコープより外側にある変数を再束縛するには、"nonlocal" 文を使えま
す。 こうした外側の変数は、nonlocal と宣言しない限り読み出し専用です。
代入しようとすると、最も内側のスコープに同名の *新しい* ローカル変数が
作られ、外側の変数は変わりません。

通常、ローカルスコープは (プログラムテキスト上の) 現在の関数のローカル
な名前を参照します。関数の外側では、ローカルスコープはグローバルな名前
空間と同じ名前空間、モジュールの名前空間を参照します。クラス定義では、
ローカルスコープの中にもう一つ名前空間が置かれます。

スコープはテキスト上で決定されていると理解することが重要です。モジュー
ル内で定義される関数のグローバルなスコープは、関数がどこから呼び出され
ても、どんな別名をつけて呼び出されても、そのモジュールの名前空間になり
ます。反対に、実際の名前の検索は実行時に動的に行われます --- とはいえ
、言語の定義は、"コンパイル" 時の静的な名前解決の方向に進化しているの
で、動的な名前解決に頼ってはいけません！ (事実、ローカルな変数は既に静
的に決定されています。)

"global" 文や "nonlocal" 文が有効でない場合、 Python では名前への代入
は常に最も内側のスコープで行われます。 代入はデータをコピーせず、名前
をオブジェクトに束縛するだけです。 削除も同様で、"del x" はローカルス
コープの名前空間から "x" の束縛を削除します。 新しい名前を導入する操作
はすべてローカルスコープを使います。 例えば "import" 文や関数定義は、
モジュール名や関数名をローカルスコープで束縛します。

"global" 文を使うと、特定の変数がグローバルスコープに存在し、そこで再
束縛されることを指示できます。 "nonlocal" 文は、特定の変数が外側のスコ
ープに存在し、そこで再束縛されることを指示します。


9.2.1. スコープと名前空間の例
-----------------------------

異なるスコープと名前空間がどのように参照されるか、また "global" および
"nonlocal" が変数の束縛にどう影響するか、この例で実演します:

   def scope_test():
       def do_local():
           spam = "local spam"

       def do_nonlocal():
           nonlocal spam
           spam = "nonlocal spam"

       def do_global():
           global spam
           spam = "global spam"

       spam = "test spam"
       do_local()
       print("After local assignment:", spam)
       do_nonlocal()
       print("After nonlocal assignment:", spam)
       do_global()
       print("After global assignment:", spam)

   scope_test()
   print("In global scope:", spam)

このコード例の出力は:

   After local assignment: test spam
   After nonlocal assignment: nonlocal spam
   After global assignment: nonlocal spam
   In global scope: global spam

このとおり、(デフォルトの) *ローカルな* 代入は *scope_test* 上の
*spam* への束縛を変更しませんでした。 "nonlocal" 代入は *scope_test*
上の *spam* への束縛を変更し、 "global" 代入はモジュールレベルの束縛を
変更しました。

また、"global" による代入の前には、グローバルスコープで *spam* がまだ
束縛されていなかったことも分かります。


9.3. クラス初見
===============

クラスでは、新しい構文を少しと、三つの新たなオブジェクト型、そして新た
な意味付けをいくつか取り入れています。


9.3.1. クラス定義の構文
-----------------------

クラス定義の最も単純な形式は、次のようになります:

   class ClassName:
       <statement-1>
       .
       .
       .
       <statement-N>

関数定義 ("def" 文) と同様、クラス定義が効果をもつにはまず実行しなけれ
ばなりません。 (クラス定義を "if" 文の分岐先や関数内部に置くことも、考
え方としてはありえます。)

実際には、クラス定義の内側にある文は、通常は関数定義になりますが、他の
文を書くこともでき、それが役に立つこともあります --- これについては後
で述べます。クラス内の関数定義は通常、メソッドの呼び出し規約で決められ
た独特の形式の引数リストを持ちます --- これについても後で述べます。

クラス定義に入ると、新しい名前空間が作られ、ローカルスコープとして使わ
れます。 したがって、ローカル変数への代入はすべてこの新しい名前空間に
対して行われます。 特に、関数定義では新しい関数の名前がここに束縛され
ます。

クラス定義から普通に (定義の終端に到達して) 抜けると、 *クラスオブジェ
クト (class object)* が生成されます。クラスオブジェクトは、基本的には
クラス定義で作成された名前空間の内容をくるむラッパー (wrapper) です。
クラスオブジェクトについては次の節で詳しく学ぶことにします。 (クラス定
義に入る前に有効だった) 元のローカルスコープが復帰し、生成されたクラス
オブジェクトは復帰したローカルスコープにクラス定義のヘッダで指定した名
前 (上の例では "ClassName") で結び付けられます。


9.3.2. クラスオブジェクト
-------------------------

クラスオブジェクトでは２種類の演算、属性参照とインスタンス生成をサポー
トしています。

*属性参照 (attribute reference)* は、Python におけるすべての属性参照で
使われている標準的な構文、 "obj.name" を使います。クラスオブジェクトが
生成された際にクラスの名前空間にあった名前すべてが有効な属性名です。従
って、以下のようなクラス定義では:

   class MyClass:
       """A simple example class"""
       i = 12345

       def f(self):
           return 'hello world'

"MyClass.i" と "MyClass.f" は有効な属性参照であり、それぞれ整数と関数
オブジェクトを返します。クラス属性も代入できるため、代入により
"MyClass.i" の値を変えられます。 "__doc__" も有効な属性で、そのクラス
に属しているドキュメンテーション文字列(docstring) 、この場合は ""A
simple example class"" を返します。

クラスの *インスタンス化 (instantiation)* には関数記法を使います。クラ
スオブジェクトのことを、クラスの新しいインスタンスを返す、引数のない関
数のように扱ってください。上記クラスで例示すると:

   x = MyClass()

は、クラスの新しい *インスタンス (instance)* を生成し、そのオブジェク
トをローカル変数 "x" へ代入します。

インスタンス化操作 (クラスオブジェクトの "呼出し") では、空のオブジェ
クトが作られます。多くのクラスでは、特定の初期状態にカスタマイズされた
オブジェクトを作りたいです。そのために、クラスには "__init__()" という
名前の特殊メソッドを定義できます。例えば次のようにします:

   def __init__(self):
       self.data = []

クラスが "__init__()" メソッドを定義している場合、クラスをインスタンス
化すると、新しく作られたクラスインスタンスに対して自動的に
"__init__()" を呼び出します。  従って この例では、新たな初期済みインス
タンスを次のようにして得られます:

   x = MyClass()

もちろん、より大きな柔軟性を持たせるために、 "__init__()" メソッドに複
数の引数をもたせることができます。その場合、次の例のように、クラスのイ
ンスタンス化操作に渡された引数は "__init__()" に渡されます。例えば、

   >>> class Complex:
   ...     def __init__(self, realpart, imagpart):
   ...         self.r = realpart
   ...         self.i = imagpart
   ...
   >>> x = Complex(3.0, -4.5)
   >>> x.r, x.i
   (3.0, -4.5)


9.3.3. インスタンスオブジェクト
-------------------------------

ところで、インスタンスオブジェクトを使うと何ができるのでしょうか？イン
スタンスオブジェクトが理解できる唯一の操作は、属性の参照です。有効な属
性名には (データ属性およびメソッドの) 二種類あります。

*データ属性 (data attribute)* は Smalltalk の「インスタンス変数」や
C++ の「データメンバ」に相当します。 データ属性を宣言する必要はありま
せん。 ローカル変数と同様に、初めて値を代入したときに作られます。 例え
ば、"x" が上で作成した "MyClass" のインスタンスなら、 次のコードは値
"16" を表示した後、追加した "counter" 属性を削除します。

   x.counter = 1
   while x.counter < 10:
       x.counter = x.counter * 2
   print(x.counter)
   del x.counter

もう一つのインスタンス属性の参照は、 *メソッド* です。メソッドとは、オ
ブジェクトに "属する" 関数のことです。

インスタンスオブジェクトで有効なメソッド名は、そのクラスによって決まり
ます。 定義上、クラス属性が関数オブジェクトであれば、そのクラスのイン
スタンスに対応するメソッドが定義されます。 この例では "MyClass.f" が関
数なので、"x.f" は有効なメソッド参照です。 一方、"MyClass.i" は関数で
はないので、"x.i" はメソッド参照ではありません。 ただし、"x.f" は
"MyClass.f" と同じものではありません。 "x.f" は関数オブジェクトではな
く、*メソッドオブジェクト (method object)* です。


9.3.4. メソッドオブジェクト
---------------------------

普通、メソッドはバインドされた直後に呼び出されます:

   x.f()

もし "x = MyClass()" であれば、上記のコードは文字列 "'hello world'" を
返すでしょう。しかしながら、必ずしもメソッドをその場で呼び出さなければ
ならないわけではありません。 "x.f" はメソッドオブジェクトであり、どこ
かに記憶しておいて後で呼び出すことができます。例えば次のコードは:

   xf = x.f
   while True:
       print(xf())

"hello world" を時が終わるまで印字し続けるでしょう。

メソッドが呼び出されるときには実際には何が起きているのでしょうか？
"f()" の関数定義では引数を一つ指定していたにもかかわらず、上の例では
"x.f()" が引数なしで呼び出されています。引数はどうなったのでしょうか？
たしか、引数が必要な関数を引数無しで呼び出すと、 Python が例外を送出す
るはずです --- たとえその引数が実際には使われなくても…。

もう答は想像できているかもしれませんね: メソッドについて特別なこととし
て、インスタンスオブジェクトが関数の第1引数として渡されます。 例では、
"x.f()" という呼び出しは、 "MyClass.f(x)" と厳密に等価なものです。 一
般に、 *n* 個の引数リストもったメソッドの呼出しは、そのメソッドのイン
スタンスオブジェクトを最初の引数の前に挿入した引数リストで、メソッドに
対応する関数を呼び出すことと等価です。

メソッドは一般に次のように動作します。 インスタンスの非データ属性を参
照すると、そのインスタンスのクラスから属性を探します。 見つかった属性
が関数オブジェクトなら、インスタンスと関数の両方への参照をまとめてメソ
ッドオブジェクトにします。 そのメソッドを呼び出すと、渡された引数の先
頭にインスタンスを加えた新しい引数リストが作られます。 そして、その引
数リストで関数を呼び出します。


9.3.5. クラス変数とインスタンス変数
-----------------------------------

一般的に、インスタンス変数はそれぞれのインスタンスについて固有のデータ
のためのもので、クラス変数はそのクラスのすべてのインスタンスによって共
有される属性やメソッドのためのものです:

   class Dog:

       kind = 'canine'         # 全インスタンスで共有されるクラス変数

       def __init__(self, name):
           self.name = name    # インスタンスごとに固有のインスタンス変数

   >>> d = Dog('Fido')
   >>> e = Dog('Buddy')
   >>> d.kind                  # すべての犬で共有
   'canine'
   >>> e.kind                  # すべての犬で共有
   'canine'
   >>> d.name                  # d 固有
   'Fido'
   >>> e.name                  # e 固有
   'Buddy'

名前とオブジェクトについて で述べたように、共有データはリストや辞書の
ような *mutable* オブジェクトで予期せぬ作用を生じることがあります。例
えば、以下のコードの *tricks* リストはクラス変数として使われるべきでは
ありません、なぜなら単一のリストがすべての *Dog* インスタンスで共有さ
れてしまうからです:

   class Dog:

       tricks = []             # クラス変数の間違った使用

       def __init__(self, name):
           self.name = name

       def add_trick(self, trick):
           self.tricks.append(trick)

   >>> d = Dog('Fido')
   >>> e = Dog('Buddy')
   >>> d.add_trick('roll over')
   >>> e.add_trick('play dead')
   >>> d.tricks                # 意図せず すべての犬で共有
   ['roll over', 'play dead']

このクラスの正しい設計ではインスタンス変数を代わりに使用するべきです:

   class Dog:

       def __init__(self, name):
           self.name = name
           self.tricks = []    # 犬ごとに新しい空リストを作る

       def add_trick(self, trick):
           self.tricks.append(trick)

   >>> d = Dog('Fido')
   >>> e = Dog('Buddy')
   >>> d.add_trick('roll over')
   >>> e.add_trick('play dead')
   >>> d.tricks
   ['roll over']
   >>> e.tricks
   ['play dead']


9.4. いろいろな注意点
=====================

インスタンスとクラスに同じ名前の属性がある場合、属性の検索ではインスタ
ンス側が優先されます。

   >>> class Warehouse:
   ...    purpose = 'storage'
   ...    region = 'west'
   ...
   >>> w1 = Warehouse()
   >>> print(w1.purpose, w1.region)
   storage west
   >>> w2 = Warehouse()
   >>> w2.region = 'east'
   >>> print(w2.purpose, w2.region)
   storage east

データ属性は、メソッドからも、オブジェクトの通常の利用者 (「クライアン
ト」) からも参照できます。 つまり、クラスを使って純粋な抽象データ型を
実装することはできません。 実際、Python にはデータの隠蔽を強制する仕組
みがなく、すべて規約に基づいています。 (一方、C で書かれた Python の実
装では、必要に応じて実装の詳細を完全に隠し、オブジェクトへのアクセスを
制御できます。 C で書く Python の拡張ではこの仕組みを使えます。)

クライアントはデータ属性を注意して使うべきです。 データ属性を書き換え
ると、メソッドが維持する不変条件を壊す可能性があります。 ただし、名前
の衝突を避ければ、クライアントはメソッドの正常な動作に影響を与えずに、
インスタンスオブジェクトへ独自のデータ属性を追加できます。 ここでも、
名前付けの規約を使うと多くの問題を避けられます。

メソッドの中から、データ属性を (または別のメソッドも！) 参照するための
短縮された記法はありません。私は、この仕様がメソッドの可読性を高めてい
ると感じています。あるメソッドを眺めているときにローカルな変数とインス
タンス変数をはっきり区別できるからです。

メソッドの最初の引数は "self" と呼ぶことが多いです。 これは単なる慣習
であり、"self" という名前自体は Python にとって特別な意味を持ちません
。 ただし、この慣習に従わないと、他の Python プログラマーにとってコー
ドが読みにくくなる可能性があります。 また、この慣習に依存する *クラス
ブラウザ (class browser)* プログラムが書かれることも考えられます。

クラス属性である関数オブジェクトはいずれも、そのクラスのインスタンスの
ためのメソッドを定義しています。関数定義は、テキスト上でクラス定義の中
に入っている必要はありません。関数オブジェクトをクラスのローカルな変数
の中に代入するのも OK です。例えば以下のコードのようにします:

   # クラス外で定義された関数
   def f1(self, x, y):
       return min(x, x+y)

   class C:
       f = f1

       def g(self):
           return 'hello world'

       h = g

これで、 "f" 、 "g" 、および "h" は、すべて "C" の属性であり関数オブジ
ェクトを参照しています。従って、これらは、すべて "C" のインスタンスの
メソッドとなります --- "h" は "g" と全く等価です。これを実践しても、大
抵は単にプログラムの読者に混乱をもたらすだけなので注意してください。

メソッドは、 "self" 引数のメソッド属性を使って、他のメソッドを呼び出す
ことができます:

   class Bag:
       def __init__(self):
           self.data = []

       def add(self, x):
           self.data.append(x)

       def addtwice(self, x):
           self.add(x)
           self.add(x)

メソッドは通常の関数と同様にグローバル名を参照できます。 メソッドのグ
ローバルスコープは、その定義を含むモジュールです (クラスがグローバルス
コープになることはありません)。 メソッドでグローバルデータを使う適切な
理由はまれですが、グローバルスコープには妥当な用途が数多くあります。
例えば、グローバルスコープにインポートした関数やモジュール、そのスコー
プで定義した関数やクラスは、メソッドからも使えます。 通常、そのメソッ
ドを含むクラス自体もこのグローバルスコープで定義されています。 次の節
では、メソッドが自身のクラスを参照したくなる理由を見ていきます。

個々の値はオブジェクトなので、 *クラス* (*型* とも言います) を持ってい
ます。それは "object.__class__" に保持されています。


9.5. 継承
=========

言うまでもなく、継承の概念をサポートしない言語機能は "クラス" と呼ぶに
値しません。派生クラス (derived class) を定義する構文は次のようになり
ます:

   class DerivedClassName(BaseClassName):
       <statement-1>
       .
       .
       .
       <statement-N>

基底クラス (base class) の名前 "BaseClassName" は、派生クラス定義の入
っているスコープからアクセスできる名前空間で定義されていなければなりま
せん。基底クラス名のかわりに任意の式を入れることもできます。これは次の
例のように、基底クラスが別モジュールで定義されているときに便利なことが
あります:

   class DerivedClassName(modname.BaseClassName):

派生クラス定義の実行は、基底クラスの場合と同じように進められます。クラ
スオブジェクトが構築される時、基底クラスが記憶されます。記憶された基底
クラスは、属性参照を解決するために使われます。要求された属性がクラスに
見つからなかった場合、基底クラスに検索が進みます。この規則は、基底クラ
スが他の何らかのクラスから派生したものであった場合、再帰的に適用されま
す。

派生クラスのインスタンス化では、特別なことは何もありません。
"DerivedClassName()" はクラスの新たなインスタンスを生成します。メソッ
ドの参照は次のようにして解決されます。まず対応するクラス属性が検索され
ます。検索は、必要に応じ、基底クラス連鎖を下って行われ、検索の結果とし
て何らかの関数オブジェクトがもたらされた場合、メソッド参照は有効なもの
となります。

派生クラスは基底クラスのメソッドを上書き (override) することができます
。メソッドは同じオブジェクトの別のメソッドを呼び出す際に何ら特殊な権限
を持ちません。このため、ある基底クラスのメソッドが、同じ基底クラスで定
義されているもう一つのメソッド呼び出しを行っている場合、派生クラスで上
書きされた何らかのメソッドが呼び出されることになるかもしれません。
(C++ プログラマへ:  Python では、すべてのメソッドは事実上 "virtual" で
す。)

派生クラスで上書きしているメソッドでは、基底クラスの同名のメソッドを置
き換えるのではなく、拡張したいのかもしれません。基底クラスのメソッドを
直接呼び出す簡単な方法があります。単に "BaseClassName.methodname(self,
arguments)" を呼び出すだけです。この仕様は、場合によってはクライアント
でも役に立ちます。 (この呼び出し方が動作するのは、基底クラスがグローバ
ルスコープの "BaseClassName" という名前でアクセスできるときだけです。)

Python には継承に関係する 2 つの組み込み関数があります:

* "isinstance()" を使うとインスタンスの型が調べられます。
  "isinstance(obj, int)" は "obj.__class__" が "int" や "int" の派生ク
  ラスの場合に限り "True" になります。

* "issubclass()" を使うとクラスの継承関係が調べられます。 "bool" は
  "int" のサブクラスなので "issubclass(bool, int)" は "True" です。し
  かし、 "float" は "int" のサブクラスではないので "issubclass(float,
  int)" は "False" です。


9.5.1. 多重継承
---------------

Python では、多重継承 (multiple inheritance) の形式もサポートしていま
す。複数の基底クラスをもつクラス定義は次のようになります:

   class DerivedClassName(Base1, Base2, Base3):
       <statement-1>
       .
       .
       .
       <statement-N>

ほとんどのシンプルな多重継承において、親クラスから継承される属性の検索
は、深さ優先で、左から右に、そして継承の階層の中で同じクラスが複数出て
くる（訳注: ダイアモンド継承と呼ばれます）場合に２度探索をしない、と考
えることができます。なので、ある属性が "DerivedClassName" で見つからな
い場合、まず "Base1" から検索され、そして（再帰的に） "Base1" の基底ク
ラスから検索され、それでも見つからなかった場合は "Base2" から検索され
る、といった具合になります。

実際には、それよりもう少しだけ複雑です。協調的な "super()" の呼び出し
のためにメソッドの解決順序は動的に変更されます。このアプローチは他の多
重継承のある言語で call-next-method として知られており、単一継承しかな
い言語の super 呼び出しよりも強力です。

検索順序を動的に決める必要があるのは、どの多重継承にも 1 つ以上のダイ
ヤモンド関係があるためです。 これは、最も下位のクラスから同じ祖先クラ
スに複数の経路でたどり着ける関係を指します。 例えば、すべてのクラスは
"object" を継承するので、多重継承では "object" に至る経路が複数ありま
す。 同じ基底クラスを何度もたどらないように、動的なアルゴリズムで検索
順序を一列に並べます。 この順序は、各クラスで指定した基底クラスの左か
ら右への順序を保ち、各祖先クラスを一度だけたどるように決まります。 さ
らに、サブクラスを作っても祖先クラス同士の優先順位が変わらない「単調性
」を保ちます。 こうした性質により、信頼性が高く拡張しやすい多重継承の
クラスを設計できます。 詳しくは Python 2.3 のメソッド解決順序 を参照し
てください。

いくつかの場合では多重継承が許されません。詳細は 多重継承 を見てくださ
い。


9.6. プライベート変数
=====================

オブジェクトの中からしかアクセス出来ない "プライベート" インスタンス変
数は、 Python にはありません。しかし、ほとんどの Python コードが従って
いる慣習があります。アンダースコアで始まる名前 (例えば "_spam") は、 (
関数であれメソッドであれデータメンバであれ) 非 public なAPIとして扱い
ます。これらは、予告なく変更されるかもしれない実装の詳細として扱われる
べきです。

クラスのプライベートメンバは、サブクラスで定義された名前との衝突を避け
るのに役立ちます。 この用途のために、Python は名前マングリング (*name
mangling*) という限定的な仕組みを備えています。 "__spam" のように、先
頭に 2 個以上、末尾に 1 個以下のアンダースコアを持つ識別子は、 テキス
ト上で "_classname__spam" に置き換えられます。 "classname" は現在のク
ラス名から先頭のアンダースコアを取り除いたものです。 対象の識別子がク
ラス定義内にあれば、構文上の位置に関係なくこの変換が行われます。

参考: 詳細と特例は、 private name mangling specifications 。

名前マングリングは、サブクラスが内部のメソッド呼び出しを壊さずにメソッ
ドをオーバーライドするのに便利です。例えば:

   class Mapping:
       def __init__(self, iterable):
           self.items_list = []
           self.__update(iterable)

       def update(self, iterable):
           for item in iterable:
               self.items_list.append(item)

       __update = update   # 元の update() メソッドのプライベートコピー

   class MappingSubclass(Mapping):

       def update(self, keys, values):
           # update() への新シグネチャ導入
           # しかし __init__() は壊さない
           for item in zip(keys, values):
               self.items_list.append(item)

上の例は、もし仮に "MappingSubclass" に "__update" 識別子を実装したと
してもきちんと動きます。 その理由は、 "Mapping" クラスではその識別子を
"_Mapping__update" に、 "MappingSubclass" クラスでは
"_MappingSubclass__update" にそれぞれ置き換えるからです。

名前マングリングの主な目的は、名前の衝突などの事故を防ぐことです。 プ
ライベートとされている変数にも、アクセスしたり値を変更したりすることは
できます。 デバッガなどでは、この性質が役立つこともあります。

"exec()" や "eval()" に渡したコードでは、呼び出し元のクラスは名前マン
グリングに使う現在のクラスとして扱われません。 これは "global" 文と同
様で、効果が及ぶのは一緒にバイトコンパイルされるコードの範囲だけです。
"getattr()"、"setattr()"、"delattr()" を使う場合や、"__dict__" を直接
参照する場合も同じ制約があります。


9.7. 残りのはしばし
===================

Pascal のレコードや C の構造体のように、名前付きのデータ項目をまとめる
型があると便利なことがあります。 Python では、この用途に "dataclasses"
を使うのが一般的です。

   from dataclasses import dataclass

   @dataclass
   class Employee:
       name: str
       dept: str
       salary: int

   >>> john = Employee('john', 'computer lab', 1000)
   >>> john.dept
   'computer lab'
   >>> john.salary
   1000

特定の抽象データ型を想定した Python コードには、その型と同じように動く
メソッドを備えたクラスを代わりに使えることがよくあります。 例えば、フ
ァイルオブジェクトから読み取ったデータをフォーマットする関数があるとし
ます。 ファイルの代わりに文字列バッファからデータを読み取る "read()"
と "readline()" メソッドを持つクラスを定義すれば、 そのインスタンスを
この関数の引数として渡せます。

Instance method objects にも属性があります。 "m.__self__" はメソッド
"m()" の属しているインスタンスオブジェクトで、"m.__func__" はそのメソ
ッドに対応する function object です。


9.8. イテレータ (iterator)
==========================

すでに気づいているでしょうが、 "for" 文を使うとほとんどのコンテナオブ
ジェクトにわたってループを行うことができます:

   for element in [1, 2, 3]:
       print(element)
   for element in (1, 2, 3):
       print(element)
   for key in {'one':1, 'two':2}:
       print(key)
   for char in "123":
       print(char)
   for line in open("myfile.txt"):
       print(line, end='')

こういう要素へのアクセス方法は明確で簡潔で使い易いものです。イテレータ
の活用は Python へ広く行き渡り、統一感を持たせています。裏では "for"
文はコンテナオブジェクトに対して "iter()" 関数を呼んでいます。関数は、
コンテナの中の要素に1つずつアクセスする "__next__()" メソッドが定義さ
れているイテレータオブジェクトを返します。これ以上要素が無い場合は、
"__next__()" メソッドは "StopIteration" 例外を送出し、その通知を受け
"for" ループは終了します。組み込みの "next()" 関数を使って
"__next__()" メソッドを直接呼ぶこともできます; この例は関数がどう働く
のかを示しています:

   >>> s = 'abc'
   >>> it = iter(s)
   >>> it
   <str_iterator object at 0x10c90e650>
   >>> next(it)
   'a'
   >>> next(it)
   'b'
   >>> next(it)
   'c'
   >>> next(it)
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
       next(it)
   StopIteration

イテレータプロトコルの裏にある仕組みを観察していれば、自作のクラスにイ
テレータとしての振舞いを追加するのは簡単です。 "__next__()" メソッドを
持つオブジェクトを返す "__iter__()" メソッドを定義するのです。クラスが
"__next__()" メソッドを定義している場合、 "__iter__()" メソッドは単に
"self" を返すことも可能です:

   class Reverse:
       """シーケンスを後ろからまわるイテレータ."""
       def __init__(self, data):
           self.data = data
           self.index = len(data)

       def __iter__(self):
           return self

       def __next__(self):
           if self.index == 0:
               raise StopIteration
           self.index = self.index - 1
           return self.data[self.index]

   >>> rev = Reverse('spam')
   >>> iter(rev)
   <__main__.Reverse object at 0x00A1DB50>
   >>> for char in rev:
   ...     print(char)
   ...
   m
   a
   p
   s


9.9. ジェネレータ (generator)
=============================

*ジェネレータ* は、イテレータを作成するための簡潔で強力なツールです。
ジェネレータは通常の関数のように書かれますが、何らかのデータを返すとき
には "yield" 文を使います。そのジェネレータに対して "next()" が呼び出
されるたびに、ジェネレータは以前に中断した処理を再開します (ジェネレー
タは、全てのデータ値と最後にどの文が実行されたかを記憶しています)。以
下の例を見れば、ジェネレータがとても簡単に作成できることがわかります:

   def reverse(data):
       for index in range(len(data)-1, -1, -1):
           yield data[index]

   >>> for char in reverse('golf'):
   ...     print(char)
   ...
   f
   l
   o
   g

ジェネレータでできることは、前の節で解説したクラスを使ったイテレータで
も実現できます。ジェネレータの定義がコンパクトになるのは "__iter__()"
メソッドと "__next__()" メソッドが自動で作成されるからです。

もう一つの重要な機能は、呼び出しと呼び出しの間にローカル変数と実行状態
が自動的に保存されることです。 このため、"self.index" や "self.data"
のようなインスタンス変数を使う方法よりも、関数を簡単に書け、コードもず
っと明確になります。

メソッドを自動生成したりプログラムの実行状態を自動保存するほかに、ジェ
ネレータは終了時に自動的に "StopIteration" を送出します。これらの機能
を組み合わせると、通常の関数を書くのと同じ労力で、簡単にイテレータを生
成できます。


9.10. ジェネレータ式
====================

単純なジェネレータは、リスト内包表記の角括弧を丸括弧に替えたような構文
で、短い式として書けます。 このジェネレータ式は、ジェネレータを関数の
引数として渡し、その関数ですぐに使う場合に適しています。 ジェネレータ
を関数として定義するより用途は限られますが、短く書けます。 また、同じ
内容のリスト内包表記よりメモリ使用量を抑えられることが多くなります。

例:

   >>> sum(i*i for i in range(10))                 # 平方和
   285

   >>> xvec = [10, 20, 30]
   >>> yvec = [7, 5, 3]
   >>> sum(x*y for x,y in zip(xvec, yvec))         # ドット積
   260

   >>> unique_words = set(word for line in page  for word in line.split())

   >>> valedictorian = max((student.gpa, student.name) for student in graduates)

   >>> data = 'golf'
   >>> list(data[i] for i in range(len(data)-1, -1, -1))
   ['f', 'l', 'o', 'g']

   >>> x = [[1,2,3], [], [4, 5]]
   >>> g = (*i for i in x)
   >>> list(g)
   [1, 2, 3, 4, 5]

多くの場合、ジェネレータ式は括弧で囲む必要があります。  ただし特例とし
て、唯一の実引数として関数に渡す場合（前述の "sum", "set", "max",
"list" の例のように）は、ジェネレータ式を追加の括弧で囲む必要がありま
せん。  すなわち、次の２つのコード片は意味的に等価です:

   >>> f(x for x in y)
   >>> f((x for x in y))

以下も同様です:

   >>> f(*x for x in y)
   >>> f((*x for x in y))

-[ 脚注 ]-

[1] 例外が一つあります。モジュールオブジェクトには、秘密の読取り専用の
    属性 "__dict__" があり、モジュールの名前空間を実装するために使われ
    ている辞書を返します; "__dict__" という名前は属性ですが、グローバ
    ルな名前ではありません。この属性を利用すると名前空間の実装に対する
    抽象化を侵すことになるので、プログラムを検死するデバッガのような用
    途に限るべきです。
