初めてのPython(23章)

Pythonのクラスの特徴

  1. 名前空間の1つ
  2. 名前空間の継承(階層化)、演算子オーバーロードが出来る

クラスオブジェクトとインスタンスオブジェクト

演算子オーバーロード

独自に定義したクラスのオブジェクトにビルドインオブジェクトのように、連結/スライシングなどに対応できるようにすること。
オーバーロードのためには、クラスに__X__という名前の特殊なメソッドを定義する。

ただ、__init__ 以外については、通常のメソッドを使って同じようなことは出来る。
→ ビルドインとインタフェースを統一したクラスを作りたいとき以外は使わなくても問題無し

[kobakoba0723@fedora13-intel64 ~]$ cat overload.py
#!/usr/bin/env python

class C1(object):
  def __init__(self, value):
    self.data = value
  
  def __add__(self, value):
    return C1(self.data + value)
  
  def __mul__(self, value):
    return C1(self.data * value)
  
  def display(self):
    print "Data: ", self.data

if __name__ == '__main__':
  a = C1("hoge")
  
  b = a + "piyo"
  c = a * 2
  
  a.display()
  b.display()
  c.display()

[kobakoba0723@fedora13-intel64 ~]$ python overload.py
Data:  hoge
Data:  hogepiyo
Data:  hogehoge
[kobakoba0723@fedora13-intel64 ~]$ 

__class__ と __bases__

__class__ は対象インスタンスがどのクラスとリンクされているかを表す。
__bases__ は対象クラスのスーパークラスを表す(タプル)

[kobakoba0723@fedora13-intel64 ~]$ cat sample.py 
#!/usr/bin/env python

class C1(object):
  pass

class C2(object):
  pass

class C3(C1, C2):
  pass

if __name__ == '__main__':
  a = C3()
  
  print "C1.__bases__ : ", C1.__bases__
  print "C1.__class__ : ", C1.__class__
  print "C3.__bases__ : ", C3.__bases__
  print "C3.__class__ : ", C3.__class__
  print "a.__class__ : ", a.__class__
  print "a.__bases__ : ", a.__bases__

[kobakoba0723@fedora13-intel64 ~]$ python sample.py 
C1.__bases__ :  (<type 'object'>,)
C1.__class__ :  <type 'type'>
C3.__bases__ :  (<class '__main__.C1'>, <class '__main__.C2'>)
C3.__class__ :  <type 'type'>
a.__class__ :  <class '__main__.C3'>
a.__bases__ : 
Traceback (most recent call last):
  File "sample.py", line 20, in <module>
    print "a.__bases__ : ", a.__bases__
AttributeError: 'C3' object has no attribute '__bases__'
[kobakoba0723@fedora13-intel64 ~]$ 

クラスオブジェクトは __class__ を属性として持ってるけど、インスタンスオブジェクトは __bases__ を属性として持っていない。
インスタンスは自分がどのクラスの派生クラスから生成されたか知る必要がないから属性が無いのかな。