トップ 一覧 ping 検索 ヘルプ RSS ログイン

Python サンプルコード オブジェクト指向の変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!!!Python サンプルコード オブジェクト指向
[Python][Python サンプルコード][言語まとめ Python][Python 標準ライブラリ概観]

!!!クラスを使用
,API,概要
,class クラス名:,クラスを作成
,def メソッド名(self,引数・・・),メンバ関数
,def __init__(self),インスタンス初期化

*メンバ関数の先頭引数にはインスタンスの参照(self)を指定する
*クラス名()でインスタンスを作成
 class Person:
   def __init__(self):
     print 'wake up'
 
   def greet(self):
     print 'hello.'
 
 x = Person()
 x.greet()
::結果
 wake up
 hello.
!!新スタイルクラスとクラシッククラス
*Version2.2以降、「新スタイルクラス」が利用可能
""「新スタイルクラス」は、__ビルトインオブジェクト(list、object等)のサブクラスとして作成する__(ビルトインオブジェクトのサブクラスは自動的に新スタイルとなる)

 # 新スタイルクラス
 class NewStyle(object):
     pass
 
 # クラシックスタイルクラス
 class OldStyle:
     pass

!ダイヤモンド継承時の属性検索順序
*新スタイルクラスとクラシッククラスでは、ダイヤモンド継承時の属性検索順序が異なる

::クラシッククラス
*属性の検索順序は以下の順序にて行われる
++下から上
++左から右(基底クラスの記述順)
*検索順(C3よりC1のほうが優先される)
{{ref_image py_classic_cls_search.jpg}}
 class C1:
     def m1(self):
         print 'C1'
 class C2(C1): 
     pass
 class C3(C1):
     def m1(self):
         print 'C3'
 class C4(C2,C3): pass
     
 c = C4()
 c.m1()    
*結果
 C1

::新スタイルクラス
*属性の検索順序は以下の順序にて行われる
++左から右(基底クラスの記述順)
++下から上
*検索順(C1よりC3のほうが優先される)
{{ref_image py_new_cls_search.jpg}}
 class C1(object):
     def m1(self):
         print 'C1'
 class C2(C1): 
     pass
 class C3(C1):
     def m1(self):
         print 'C3'
 
 class C4(C2,C3): pass
     
 c = C4()
 c.m1()   
*結果
 C3
!!!コンストラクタ
!!基底クラスのコンストラクタを呼び出す
::例
 # -*- coding: utf-8 -*-
 
 class Base(object):
     def __init__(self, x):
         self.x = x
     def get_v(self):
         return self.x
 
 class Deriv(Base):
     def __init__(self, x):
         # 基底クラスのコンストラクタを呼び出す
         super(Deriv, self).__init__(x)
     def get_x(self):
         # 基底クラスを指定してメソッドを呼び出す
         return super(Deriv, self).get_v()
 
 b = Base('base')
 print b.get_v()
 
 d = Deriv('deriv')
 print d.get_v()
 print d.get_x()
 
::結果
 base
 deriv
 deriv

!!!カプセル化
!!プロパティ
::通常の記法
 class Spam(object):
     def __init__(self):
         self.__ham = 'spam.ham'
     def get_ham(self):
         return self.__ham
     def set_ham(self, value):
         self.__ham = value
     def del_ham(self):
         del self.__ham
     ham = property(get_ham, set_ham, del_ham, 'ham property')

::関数デコレータ使用
*http://www17.atpages.jp/~lambda7/py/decorator.html
 class Egg(object):
     def __init__(self):
         self.__ham = 'egg.ham'
     @property
     def ham(self):
         return self.__ham
     @ham.setter
     def ham(self, value):
         self.__ham = value
     @ham.deleter
     def ham(self):
         del self.__ham

!!!メソッドオブジェクト
::メソッドをオブジェクトとして扱う
 class Person:
   def greet(self):
     print 'hello.'
 
 x = Person()
 y = x.greet
 
 print type(y)
 y()
 
::結果
 <type 'instancemethod'>
 hello.

!!インスタンスと結びついている
 >>> class Foo:
 ...     f1 = ''
 ...     def bar(self, msg):
 ...             print msg
 ...             self.f1 = 'called'
 ...     def status(self):
 ...             print self.f1
 ...
 >>> f =  Foo()
 >>> x = f.bar
 >>> x('test')
 test
 >>> f.status()
 called
!!!継承
,API,概要
,class 派生クラス名(基底クラス名):,基底クラスから派生クラスを作成

 class Person(object):
     def __init__(self):
         self._msg = '...'
     def greet(self):
         print self._msg
 
 class Japanese(Person):
     def __init__(self):
         self._msg = 'ohayo-'
 
 class American(Person):
     def __init__(self):
         self._msg = 'hello'
::結果
 >>> x = Japanese()
 >>> x.greet()
 ohayo-
 >>> y = American()
 >>> y.greet()
 hello
 >>> z = Person()
 >>> z.greet()
 ...        

!!!多重継承
,API,概要
,class 派生クラス名(基底クラス名,基底クラス名,・・・):,基底クラス(複数)から派生クラスを多重継承して作成
,pass,処理がないのを明示

 class Person:
     def speak(self):
         print 'hello'
 
 class Bird:
     def fly(self):
         print 'flying in the sky'
 
 class BirdMan(Person, Bird):
     pass
 
 x = BirdMan()
 x.speak()
 x.fly()

!!!ポリモーフィズム
 class Animal:
   voice = '...'
   def cry(self):
     print self.voice
 
 class Cat(Animal):
   voice = 'nya-'
 
 class Dog(Animal):
   voice = 'wan'
 
 c = Cat()
 d = Dog()
 
 mypet = [c, d]
 for pet in mypet:
   pet.cry()
::結果
 nya-
 wan
!!!クラスのインスタンスかを調べる

!!インスタンスが指定の型か調べる
*isinstance()を使用する
 >>> l = ['a','b','c']
 >>> isinstance(l, list)
 True

!!インスタンスが指定の型か同時に調べる
*調査する型にタプルを指定

 >>> t = (1,2,3)
 >>> isinstance(t, (list, tupli))
 >>> isinstance(t, (list, tuple))
 True

!!!クラスのサブクラスかを調べる
*issubclass()を使用する
*複数同時に調べる場合、タプルを指定

 >>> class base_cls1:
 ...     pass
 ...
 >>> class base_cls2:
 ...     pass
 ...
 >>> class driv_cls(base_cls1, base_cls2):
 ...     pass
 ...
 >>> c = driv_cls()
 >>> isinstance(c, (base_cls1, base_cls2))
 True
 >>> issubclass(driv_cls, (base_cls1, base_cls2))
 True