プログラマーになりたい。

プログラミングや写真や本や読書会のことや、日常のこと。

Pythonチュートリアル読んだ

Guido van Rossum, 鴨澤眞夫(訳)『Pythonチュートリアル』(オライリー)の方ね。
よんだだけなんですが。


JavaOOPしかやってないので用語体系がちがいすぎて背筋のあたりからぺっきぺき音がしそうだ。刺激強すぎ。Rのオブジェクトもそうだし、Haskell/Curryのデータ型とかもそうなんだけど、違う世界を見ると、いかに自分が狭いとこで生きていたか見せつけられた気分になる。


まず用語が微妙に違う。

オブジェクト多すぎ…。
メモするのがめんどいので、とりあえずウェブ版のチュートリアルからコピペしておく。
というか、何か、メソッドオブジェクトとか、オブジェクトの種類が多い。


それはそうと、

データ属性ではないインスタンス属性が参照された時は、そのクラスが検索されます。
その名前が有効なクラス属性を表している関数オブジェクトなら、
インスタンスオブジェクトと見つかった関数オブジェクト (へのポインタ) を
抽象オブジェクト: すなわちメソッドオブジェクトに
パック (pack) して(引用注:メソッドオブジェクトを)作成します。

メソッドオブジェクトは、引数リストを伴って呼び出される際に再度アンパック (unpack) され、
新たな引数リストがインスタンスオブジェクトとオリジナルの引数リストから新たな引数リストが構成され、
新たな引数リストを使って関数オブジェクトを呼び出します。(ウェブ)

あるいは

データ属性でないインスタンス属性が参照されると、クラスが検索される。
名前が有効なクラス属性を指しており、この属性が関数オブジェクトであれば、
抽象オブジェクトの中に
インスタンスオブジェクトと、この関数オブジェクトを
パッキングする(ポインタで)ことで、メソッドオブジェクトを作成する。

メソッドオブジェクトが引数付きでコールされたときはこれをアンパックし、
インスタンスオブジェクトと引数リストを使って新たな引数リストを作り、
関数オブジェクトにこの新しい引数リストを渡してコールする。(オライリー)

って…。(改行引用者)


ったくもううっさい!!*1 ほら、「さん、はい」でもう一度いってごらん?

…などと皮肉っててもしょうがないので、あとでちゃんと解読します、はい。
当然、英語版もあるよー。

When an instance attribute is referenced that isn’t a data attribute, its class is searched.
If the name denotes a valid class attribute that is a function object,
a method object is created by packing (pointers to) the instance object and the function object
just found together in an abstract object: this is the method object.

When the method object is called with an argument list,
a new argument list is constructed from the instance object and the argument list,
and the function object is called with this new argument list.

以下は引用

9.3.1 クラス定義の構文


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


9.3.2 クラスオブジェクト

クラスオブジェクトでは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 へ代入します。


インスタンス生成操作 (クラスオブジェクトの ``呼出し'') を行うと、 空のオブジェクト (empty object) を生成します。多くのクラスは、 オブジェクトを作成する際に、カスタマイズされた特定の初期状態に なってほしいと望んで います。従って、クラスでは __init__() という名前の特別な メソッド定義することができます。


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

もうひとつのインスタンス属性は メソッド (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 はメソッドオブジェクトであり、

もしもまだメソッドの働きかたを理解できなければ、一度実装を見てみると事情がよく分かるかもしれません。データ属性ではないインスタンス属性が参照された時は、そのクラスが検索されます。その名前が有効なクラス属性を表している関数オブジェクトなら、インスタンスオブジェクトと見つかった関数オブジェクト (へのポインタ) を抽象オブジェクト: すなわちメソッドオブジェクトにパック (pack) して作成します。メソッドオブジェクトは、引数リストを伴って呼び出される際に再度アンパック (unpack) され、新たな引数リストがインスタンスオブジェクトとオリジナルの引数リストから新たな引数リストが構成され、新たな引数リストを使って関数オブジェクトを呼び出します。


*1:これは上記引用の直前の文章:「もしもまだメソッドの働きかたを理解できなければ、一度実装を見てみると事情がよく分かるかもしれません」(ウェブ版)、「メソッドの動作をまだ理解できない向きは、実装を見ると解りやすいと思う。」(オライリー版)に対する、もしもじゃない!どうせまだですよ><!!というひがみ。

Creative Commons License ©2007-2021 IIDA Munenori.