クラスの定義とインスタンスの作成
クラスを定義するには、class 文を使う。もちろん定義の中身はインデントされたブロックになっている。
class Person: def __init__(self, name): self.name = name def greeting(self): print "Hello, I'm " + self.name + "!" if __name__ == '__main__': andy = Person("Andy") andy.greeting() print andy.name
__init__ は特殊メソッドのひとつで、インスタンスの初期化に使われる。Ruby の initialize みたいなもんだな。ここでは name アトリビュート(インスタンス変数みたいなもの)を設定している。
メソッドはもうひとつ、greeting を定義してみた。それにしても、いちいち self を引数に含めなきゃいけないのは面倒だよなぁ。
インスタンスの作成は、クラス名を関数のように呼び出して行う。new とかはない。
実行結果:
^o^ > python person.py Hello, I'm Andy! Andy
1行目の出力が greeting メソッドを呼び出した結果で、2行目の出力が name アトリビュートにアクセスした結果だ。
アトリビュートの追加
アトリビュートは Ruby インスタンス変数と違って勝手に新しいものを追加できる。やってみよう。
>>> from person import Person >>> andy = Person("Andy") >>> andy.age Traceback (most recent call last): File "", line 1, in AttributeError: Person instance has no attribute 'age' >>> andy.age = 32 >>> andy.age 32
andy.age に代入する前の段階では、アクセスしてもエラー(’age’なんてアトリビュート無いよ)が出ているが、いったん代入すると、今度は代入した値が返ってくる。これは、インスタンスにアトリビュートを追加したのであって、クラスに追加したのではないことに注意。その証拠に別のインスタンスを作ってみても age アトリビュートはない。
>>> bill = Person("Bill") >>> bill.age Traceback (most recent call last): File "", line 1, in AttributeError: Person instance has no attribute 'age'
クラスの定義にないアトリビュートをインスタンスに追加できるというのは面白い。
インスタンスにメソッドを代入する
インスタンスに代入できるのはアトリビュートだけじゃない。メソッドだって代入できる。
>>> andy.hello() Traceback (most recent call last): File "", line 1, in AttributeError: Person instance has no attribute 'hello' >>> andy.hello = andy.greeting >>> andy.hello() Hello, I'm Andy!
これってどうなんだよ。さすがに違和感があるぞ。もしかして bill に andy のメソッドを代入もできるのか?
>>> bill.hello = andy.hello >>> bill.hello() Hello, I'm Andy!
できた。うわぁ、これは気持ちが悪い。
なんか妙に自由度が高すぎるように思うなぁ。
dir関数
dir 関数を使うとインスタンスの持っているアトリビュートの一覧を得ることができる。
>>> dir(andy) ['__doc__', '__init__', '__module__', 'age', 'greeting', 'hello', 'name']
これをみると、アトリビュート(name、age)とメソッド(greeting、hello)が一緒に並んでいる。要するに Python ではメソッドもアトリビュートの一種ってことらしい。だから代入ができるのも道理ってわけだ。