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

Python は、他のプログラミング言語と比較して、最小限の構文と意味付けを
使ってクラスを言語に追加しています。 Python のクラスは、 C++ と
Modula-3 のクラスメカニズムを混ぜたものです。 Python のクラス機構はオ
ブジェクト指向プログラミングの標準的な機能を全て提供しています。クラス
の継承メカニズムは、複数の基底クラスを持つことができ、派生クラスで基底
クラスの任意のメソッドをオーバライドすることができます。メソッドでは、
基底クラスのメソッドを同じ名前で呼び出すことができます。オブジェクトに
は任意の種類と数のデータを格納することができます。モジュールと同じく、
クラス機構も Python の動的な性質に従うように設計されています。クラスは
実行時に生成され、生成後に変更することができます。

C++ の用語で言えば、通常のクラスメンバ (データメンバも含む) は (プライ
ベート変数とクラスローカルな参照 に書かれている例外を除いて) *public*
であり、メンバ関数はすべて *仮想関数(virtual)* です。 Module-3 にある
ような、オブジェクトのメンバをメソッドから参照するための短縮した記法は
使えません: メソッド関数の宣言では、オブジェクト自体を表す第一引数を明
示しなければなりません。第一引数のオブジェクトはメソッド呼び出しの際に
暗黙の引数として渡されます。 Smalltalk に似て、クラスはそれ自体がオブ
ジェクトです。そのため、 import や名前変更といった操作が可能です。 C++
や Modula-3 と違って、ユーザーは組込み型を基底クラスにして拡張を行えま
す。また、C++ とは同じで Modula-3 とは違う点として、特別な構文を伴うほ
とんどの組み込み演算子 (算術演算子 (arithmetic operator) や添字表記)
はクラスインスタンスで使うために再定義できます。

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


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

オブジェクトには個体性があり、同一のオブジェクトに(複数のスコープから)
複数の名前を割り当てることができます。この機能は他の言語では別名づけ
(ailias) として知られています。 Python を一見しただけでは、別名づけの
重要性は分からないことが多く、変更不能な基本型 (数値、文字列、タプル)
を扱うときには無視して差し支えありません。しかしながら、別名付けは、リ
ストや辞書や他の多くの型など、変更可能な型を扱う Python コード上で驚く
べき効果があります。別名付けはいくつかの点でポインタのように振舞い、こ
のことは通常はプログラムに利するように使われます。例えば、オブジェクト
の受け渡しは、実装上はポインタが渡されるだけなのでコストの低い操作にな
ります。また、関数があるオブジェクトを引数として渡されたとき、関数の呼
び出し側からオブジェクトに対する変更を見ることができます --- これによ
り、 Pascal にあるような二つの引数渡し機構をもつ必要をなくしています。


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__" という名前のモジュールの一部分であるとみなされる
ので、独自の名前空間を持つことになります。 (組み込みの名前は実際にはモ
ジュール内に存在します。そのモジュールは "__builtin__" と呼ばれていま
す。)

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

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

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

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

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

* 次のスコープは、現在のモジュールのグローバルな名前を持っています。

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

名前が global と宣言されている場合、その名前に対する参照や代入は全て、
モジュールのグローバルな名前の入った中間のスコープに対して直接行われま
す。そうでない場合、最も内側のスコープより外側にある変数は全て読み出し
専用となります。 (そのような変数に対する書き込みは、単に *新しい* ロー
カル変数をもっとも内側のスコープで作成し、外部のスコープの値は変化しま
せん)

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

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

Python 特有の癖として、代入を行うと -- どの "global" 文も有効でない場
合は -- 名前がいつも最も内側のスコープに入るというものがあります。代入
はデータのコピーを行いません --- 単に名前をオブジェクトに結びつける
(bind) だけです。オブジェクトの削除でも同じです: "del x" は、 "x" をロ
ーカルスコープが参照している名前空間から削除します。実際、新たな名前を
導入する操作は全てローカルスコープを用います。とりわけ、 import 文や関
数定義は、モジュールや関数の名前をローカルスコープに結び付けます。
("global" 文を使えば、特定の変数がグローバルスコープにあることを示せま
す。)


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++の "データメンバ" に相当します。データ属性を宣言する必要はあ
りません。ローカルな変数と同様に、これらの属性は最初に代入された時点で
湧き出てきます。例えば、上で生成した "MyClass" のインスタンス "x" に対
して、次のコードを実行すると、値 "16" を印字し、 "x" の痕跡は残りませ
ん:

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

もうひとつのインスタンス属性は *メソッド (method)* です。メソッドとは
、オブジェクトに "属している" 関数のことです。(Python では、メソッドと
いう用語はクラスインスタンスだけのものではありません。オブジェクト型に
もメソッドを持つことができます。例えば、リストオブジェクトには、
append, insert, remove, sort などといったメソッドがあります。とはいえ
、以下では特に明記しない限り、クラスのインスタンスオブジェクトのメソッ
ドだけを意味するものとして使うことにします。)

インスタンスオブジェクトで有効なメソッド名は、そのクラスによります。定
義により、クラスの全てのo関数オブジェクトである属性がインスタンスオブ
ジェクトの妥当なメソッド名に決まります。従って、例では、 "MyClass.f"
は関数なので、 "x.f" はメソッドの参照として有効です。しかし、
"MyClass.i" は関数ではないので、 "x.i" はメソッドの参照として有効では
ありません。 "x.f" は "MyClass.f" と同じものではありません --- 関数オ
ブジェクトではなく、 *メソッドオブジェクト (method object)* です。


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

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

   x.f()

"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'         # class variable shared by all instances

       def __init__(self, name):
           self.name = name    # instance variable unique to each instance

   >>> d = Dog('Fido')
   >>> e = Dog('Buddy')
   >>> d.kind                  # shared by all dogs
   'canine'
   >>> e.kind                  # shared by all dogs
   'canine'
   >>> d.name                  # unique to d
   'Fido'
   >>> e.name                  # unique to e
   'Buddy'

名前とオブジェクトについて で議論したように、共有データはリストや辞書
のような *mutable* オブジェクトが関与すると驚くべき効果を持ち得ます。
例えば、以下のコードの *tricks* リストはクラス変数として使われるべきで
はありません、なぜならたった一つのリストがすべての *Dog* インスタンス
によって共有されることになり得るからです:

   class Dog:

       tricks = []             # mistaken use of a class variable

       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                # unexpectedly shared by all dogs
   ['roll over', 'play dead']

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

   class Dog:

       def __init__(self, name):
           self.name = name
           self.tricks = []    # creates a new empty list for each dog

       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. いろいろな注意点
=====================

データ属性は同じ名前のメソッド属性を上書きしてしまいます。大規模なプロ
グラムでみつけにくいバグを引き起こすことがあるこの偶然的な名前の衝突を
避けるには、衝突の可能性を最小限にするような規約を使うのが賢明です。可
能な規約としては、メソッド名を大文字で始める、データ属性名の先頭に短い
一意な文字列 (あるいはただの下線) をつける、またメソッドには動詞、デー
タ属性には名詞を用いる、などがあります。

データ属性は、メソッドから参照できると同時に、通常のオブジェクトのユー
ザ ("クライアント") からも参照できます。言い換えると、クラスは純粋な抽
象データ型として使うことができません。実際、 Python では、データ隠蔽を
補強するための機構はなにもありません --- データの隠蔽はすべて規約に基
づいています。 (逆に、C 言語で書かれた Python の実装では実装の詳細を完
全に隠蔽し、必要に応じてオブジェクトへのアクセスを制御できます。この機
構は C 言語で書かれた Python 拡張で使うことができます。)

クライアントはデータ属性を注意深く扱うべきです --- クライアントは、メ
ソッドが維持しているデータ属性の不変式を踏みにじり、台無しにするかもし
れません。クライアントは、名前の衝突が回避されている限り、メソッドの有
効性に影響を及ぼすことなくインスタンスに独自の属性を追加することができ
る、ということに注意してください --- ここでも、名前付けの規約は頭痛の
種を無くしてくれます。

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

よく、メソッドの最初の引数を "self" と呼びます。この名前付けは単なる慣
習でしかありません。 "self" という名前は、 Python では何ら特殊な意味を
持ちません。とはいえ、この慣行に従わないと、コードは他の Python プログ
ラマにとってやや読みにくいものとなります。また、 *クラスブラウザ
(class browser)* プログラムがこの慣行をあてにして書かれているかもしれ
ません。

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

   # Function defined outside the class
   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)

メソッドは、通常の関数と同じようにしてグローバルな名前を参照します。あ
るメソッドに関するグローバルスコープは、その定義を含むモジュールです。
(クラスはグローバルなスコープとして用いられることはありません。) メソ
ッドでグローバルなデータを使う良い理由はほとんどありませんが、グローバ
ルなスコープを使うべき場面は多々あります。一つ挙げると、メソッド内から
、グローバルなスコープに import された関数やモジュールや、そのモジュー
ル中で定義された関数やクラスを使うことができます。通常、メソッドの入っ
ているクラス自体はグローバルなスコープ内で定義されています。次の節では
、メソッドが自分のクラスを参照する理由として正当なものを見てみましょう
。

個々の値はオブジェクトなので、 *クラス* (*型* とも言います) を持ってい
ます。それは "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" です。し
  かし、 "unicode" は "str" のサブクラスではない (単に共通の祖先
  "basestring" を共有している) ので "issubclass(unicode, str)" は
  "False" です。


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

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

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

旧形式のクラスでは、名前解決規則は単に、深さ優先、左から右へ、だけです
。従って、ある属性が "DerivedClassName" で見つからなければ "Base1" で
検索され、次に "Base1" の基底クラスで (再帰的に) 検索されます。それで
も見つからなければはじめて "Base2" で検索される、といった具合です。

(人によっては、幅優先 (breadth first) --- "Base2" と "Base3" を検索し
てから "Base1" の基底クラスで検索する --- のほうが自然に思うかもしれま
せん。しかしながら、幅優先の検索では、 "Base1" の特定の属性のうち、実
際に定義されているのが "Base1" なのか、その基底クラスなのかを知らなけ
れば、 "Base2" の属性との名前衝突がどんな結果をもたらすのか分からない
ことになります。深さ優先規則では、 "Base1" の直接の属性と継承された属
性とを区別しません。)

新スタイルクラス(*new-style class*) では、協調的な "super()" の呼び出
しのためにメソッドの解決順序は動的に変更されます。このアプローチは他の
多重継承のある言語で call-next-method として知られており、単一継承しか
ない言語の super 呼び出しよりも強力です。

新スタイルクラスについて、多重継承の全ての場合に 1 つかそれ以上のダイ
ヤモンド継承 (少なくとも 1 つの祖先クラスに対し最も下のクラスから到達
する経路が複数ある状態) があるので、動的順序付けが必要です。例えば、全
ての新形式のクラスは "object" を継承しているので、どの多重継承でも
"object" へ到達するための道は複数存在します。基底クラスが複数回アクセ
スされないようにするために、動的アルゴリズムで検索順序を直列化し、各ク
ラスで指定されている祖先クラスどうしの左から右への順序は崩さず、各祖先
クラスを一度だけ呼び出し、かつ一様になる (つまり祖先クラスの順序に影響
を与えずにサブクラス化できる) ようにします。まとめると、これらの特徴の
おかげで信頼性と拡張性のある多重継承したクラスを設計することができるの
です。さらに詳細を知りたければ、
https://www.python.org/download/releases/2.3/mro/ を見てください。


9.6. プライベート変数とクラスローカルな参照
===========================================

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

クラスのプライベートメンバについて適切なユースケース(特にサブクラスで
定義された名前との衝突を避ける場合)があるので、マングリング(*name
mangling*) と呼ばれる、限定されたサポート機構があります。 "__spam" (先
頭に二個以上の下線文字、末尾に一個以下の下線文字) という形式の識別子は
、 "_classname__spam" へとテキスト置換されるようになりました。ここで
"classname" は、現在のクラス名から先頭の下線文字をはぎとった名前になり
ます。このような難号化 (mangle) は、識別子の文法的な位置にかかわらず行
われるので、クラス定義内に現れた識別子全てに対して実行されます。

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

   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   # private copy of original update() method

   class MappingSubclass(Mapping):

       def update(self, keys, values):
           # provides new signature for update()
           # but does not break __init__()
           for item in zip(keys, values):
               self.items_list.append(item)

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

難号化の規則は主に不慮の事故を防ぐためのものだということに注意してくだ
さい; 確信犯的な方法で、プライベートとされている変数にアクセスしたり変
更することは依然として可能なのです。デバッガのような特殊な状況では、こ
の仕様は便利ですらあります。

Notice that code passed to "exec", "eval()" or "execfile()" does not
consider the classname of the invoking  class to be the current class;
this is similar to the effect of the  "global" statement, the effect
of which is likewise restricted to  code that is byte-compiled
together.  The same restriction applies to "getattr()", "setattr()"
and "delattr()", as well as when referencing "__dict__" directly.


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

Pascal の "レコード (record)" や、C 言語の "構造体 (struct)" のような
、名前つきのデータ要素を一まとめにするデータ型があると便利なことがあり
ます。空のクラス定義を使うとうまくできます:

   class Employee:
       pass

   john = Employee()  # Create an empty employee record

   # Fill the fields of the record
   john.name = 'John Doe'
   john.dept = 'computer lab'
   john.salary = 1000

ある特定の抽象データ型を要求する Python コードの断片に、そのデータ型の
メソッドをエミュレーションするクラスを代わりに渡すことができます。例え
ば、ファイルオブジェクトから何らかのデータを構築する関数がある場合、
"read()" と "readline()" を持つクラスを定義して、ファイルではなく文字
列バッファからデータを取得するようにしておき、引数として渡すことができ
ます。

インスタンスメソッドオブジェクトにも属性があります。 "m.im_self" はメ
ソッド "m()" の属しているインスタンスオブジェクトで、 "m.im_func" はメ
ソッドに対応する関数オブジェクトです。


9.8. 例外はクラスであってもよい
===============================

ユーザ定義の例外をクラスとして識別することもできます。このメカニズムを
使って、拡張可能な階層化された例外を作成することができます。

新しい二つの (意味付け的な) 形式の "raise" 文があります:

   raise Class, instance

   raise instance

第一の形式では、 "instance" は "Class" またはその派生クラスのインスタ
ンスでなければなりません。第二の形式は以下の表記の短縮された記法です。

   raise instance.__class__, instance

"except" 節のクラスは、例外と同じクラスか基底クラスのときに互換
(compatible)となります。 (逆方向では成り立ちません --- 派生クラスの例
外がリストされている except 節は基底クラスの例外と互換ではありません)
。例えば、次のコードは、 B, C, D を順序通りに出力します:

   class B:
       pass
   class C(B):
       pass
   class D(C):
       pass

   for c in [B, C, D]:
       try:
           raise c()
       except D:
           print "D"
       except C:
           print "C"
       except B:
           print "B"

except 節が逆に並んでいた場合 ("except B" が最初にくる場合)、 B, B, B
と出力されるはずだったことに注意してください --- 最初に一致した except
節が駆動されるのです。

処理されないクラスの例外に対してエラーメッセージが出力されるとき、まず
クラス名が出力され、続いてコロン、スペース、最後に組み込み関数 "str()"
を使って文字列に変換したインスタンスが出力されます。


9.9. イテレータ (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,

こうしたアクセス方法は明確で、簡潔で、かつ便利なものです。イテレータの
使用は Python 全体に普及していて、統一性をもたらしています。背後では、
"for" 文はコンテナオブジェクトの "iter()" を呼び出しています。この関数
は "next()" メソッドの定義されたイテレータオブジェクトを返します。
"next()" メソッドは一度コンテナ内の要素に一度に一つづつアクセスします
。コンテナ内にアクセスすべき要素がなくなると、 "next()" は
"StopIteration" 例外を送出し、 "for" ループを終了させます。実際にどの
ように動作するかを以下の例に示します:

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

イテレータプロトコルの背後にあるメカニズムを一度目にすれば、自作のクラ
スにイテレータとしての振る舞いを追加するのは簡単です。 "__iter__()" メ
ソッドを定義して、 "next()" メソッドを持つオブジェクトを返すようにして
ください。クラス自体で "next()" を定義している場合、 "__iter__()" では
単に "self" を返すようにできます:

   class Reverse:
       """Iterator for looping over a sequence backwards."""
       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.10. ジェネレータ (generator)
==============================

ジェネレータ(*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.11. ジェネレータ式
====================

単純なジェネレータなら式として簡潔にコーディングできます。 その式はリ
スト内包表記に似た構文を使いますが、角括弧ではなく丸括弧で囲います。
ジェネレータ式は、関数の中でジェネレータをすぐに使いたいような状況のた
めに用意されています。 ジェネレータ式は完全なジェネレータの定義よりコ
ンパクトですが、ちょっと融通の効かないところがあります。 同じ内容を返
すリスト内包表記よりはメモリに優しいことが多いという利点があります。

例:

   >>> sum(i*i for i in range(10))                 # sum of squares
   285

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

   >>> from math import pi, sin
   >>> sine_table = dict((x, sin(x*pi/180)) for x in range(0, 91))

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

-[ 注記 ]-

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