pythonオブジェクト向けプログラミング(1)

8608 ワード

オブジェクト向けプログラミングOOP
pythonクラス
  • 継承:最上位クラスの共通属性を継承し、コード再利用性
  • を向上させることを目的として、共通の場合に一度実現する.
  • の組み合わせ:複数のコンポーネントオブジェクトが組み合わされ、複数のオブジェクトが協力して対応する命令を完了することによって、各コンポーネントはクラスとして書くことができ、独自の属性と動作
  • を定義する.
  • とモジュールの違い:メモリ内のモジュールには1つのインスタンスしかなく、リロードによって最新のコードを取得するしかなく、クラスには複数のインスタンス
  • がある.
    pythonクラスの具体的な特徴
  • マルチインスタンス
  • クラスは、オブジェクトインスタンスを生成するファクトリ
  • である.
  • クラスが呼び出されるたびに、独立したネーミングスペースの新しいオブジェクト
  • が生成されます.
  • 各オブジェクトに格納データは異なる
  • である.
  • 継承によるカスタマイズ
  • クラスの外部で属性
  • を再定義する.
  • ネーミングスペースの階層を作成し、クラスが作成するオブジェクトに使用される変数名
  • を定義します.
  • 演算子の再ロード
  • 特定のプロトコルを提供する方法に従って、オブジェクトを定義して、組み込みタイプのいくつかの演算
  • に応答することができる.

    pythonマルチインスタンス
  • s 1:クラステンプレートの定義とインスタンスオブジェクトの作成
  • ## person.py
    ##      
    class Person:
        ## python                           
        def __init__(self,name,job=None,pay=0):
            self.name = name
            self.job = job
            self.pay = pay
            
        def __str__(self):
            return "the name[%s] - the job[%s] - the pay[%d]" % (self.name,self.job,self.pay)
    
    ##        
    tom = Person("tom")
    jack = Person("jack",job="market",pay=20)
    print(tom)
    print(jack)
    
    >>> python person.py
    the name[tom] - the job[None] - the pay[0]
    the name[jack] - the job[market] - the pay[20]
    
    ##   :
    1)                      
    2)tom jack                    ,           
    3)         python     print      
    
    ##            ,           
    if __name__ == '__main__':
        tom = Person("tom")
        jack = Person("jack",job="market",pay=20)
        print(toml)
        print(jackl)
    
    >>> python person.py
    the name[toml] - the job[None] - the pay[0]
    the name[jackl] - the job[market] - the pay[20]
    
    >>> import person
    ##       
    
  • s 2:追加動作方法
  • ## python OOP            ,     ,      
    
    ##  OOP     last name
    print(jack.name.split()[-1])
    
    ## OOP        
    class Person:
        ....
        
        def getLastName(self):
            return self.name.split()[-1]
    
    ##     
    print(jack.getLastName()
    
  • s 3:演算子リロード
  • ##                              ,  __str__              
    class Person:
        ...
        def __str__(self):
            list = []
            for k,v in self.__dict__.items():       ##                ,                 
                list.append("%s -- %s" % (k,v))
            str =  ",".join(list)
            return "Person[%s]" % str
            
    ##                 
    >>> print(tom)
    Person[pay -- 0,name -- tom,job -- None]
    
  • s 4:サブクラスによるカスタム動作
  • ##        ,              
    class Person:
        ....
        def giveRaise(self,percent):
            self.pay = self.pay * (1 + percent)
    
    class Manager(Person):
         def giveRaise(self,percent,bouns=.10):
            ##          self  ,     self,self            ,            
            Person.giveRaise(self,percent + bouns)      
        
    ##   python      ,      .  (self,parameters)     ,       , java       super.       ,    
    
    ##   
    p1 = Person("p1",job="dev",pay=11000)
    p2 = Manager("p2",job="dev",pay=11000)
    >>> print(p1.giveRaise(.10))        
    >>> print(p2.giveRaise(.10))
    Person[name -- p1,job -- dev,pay -- 12100.000000000002]
    Person[name -- p2,job -- dev,pay -- 13200.0]
    
    ##   :
    1)python              ,                    ,            
    2)    python                           
    3)python               ,         
    
  • s 5:カスタムコンストラクタ
  • ##   Manager ,     
    class Manager(Person):
        def __init__(self,name,pay = 0):
            Person.__init__(self,name,job = "manager",pay = pay)
    
    >>> tom = Manager("tomk",pay=11000)
    >>> print(tom)
    Person[pay -- 13200.0,name -- tomk,job -- manager]
    
  • s 6:内省ツールの使用(他のプログラミング言語の「反射」)
  • 問題説明1:Manager印刷表示の情報はPersonであり、実際にはManagerを表示すべき情報
  • である.
  • 問題説明2:Managerがinitに属性を追加する、ハードコーディングであれば印刷された情報では新しい属性情報を表示できない
  • .
    ##   1     :
                   instance.__class__  
       ,      __name__   __bases__             
    
    p1 = Person("p1",job="dev",pay=11000)
    p2 = Manager("p2",pay=11000)
    >>> print(p1.__class__.__name__)
    Person
    >>> print(p1.__class__.__bases__)
    (,)
    
    >>> print(p2.__class__.__name__)
    Manager
    >>> print(p2.__class__.__bases__)
    (,)
    
    
    ##   2     :
         object.__dict__                
    
    ##    person    __dict__           
    >>> print(p1)
    Person[job -- dev,name -- p1,pay -- 11000]
    
    ##        
    p1.age = 10            
    p1.hobby = "maths"      
    >>> print(p1)
    Person[pay -- 11000,hobby -- maths,age -- 10,job -- dev,name -- p1]
    
    ##    Person          
    class Person:
        def get_all_attrs(self):
            attrs = []
            for key,value in self.__dict__.items():
                attrs.append("%s==%s" % (key,value))
            return ",".join(attrs)
    
        def __str__(self):
            return "%s[%s]" % (self.__class__.__name__,self.get_all_attrs())
    
    >>> print(p1)
    Person[hobby==maths,name==p1,job==dev,pay==11000,age==10]
    >>> print(p2)
    Manager[name==p2,pay==11000,job==manager]
    
    ##                dir  
    
    ##      OOP
    https://github.com/xiaokunliu/python-code/tree/master/01base/OOP
    
  • s 7:オブジェクトの永続化
  • pickle:任意のpythonオブジェクトとバイト列との間のシーケンス化
  • dbm:文字列
  • を格納するために、キーによってアクセス可能なファイルシステムを実現する.
  • shelve:pythonオブジェクトを上記2つのモジュールを使用して1つのファイルに格納、すなわちpickle処理後のオブジェクトをキーで格納dbmのファイルに格納する
  • .
    ## pickle
    ##          
    f1 = open("pickle.db","wb+")
    pickle.dump(p1,f1)  ##         , open("pickle.db","wb+"),   pickle        EOFError: Ran out of input 
    f1.close()
    
    ##           
    string = pickle.dumps(p1)
    
    ##      
    f = open("pickle.db","rb")
    p = pickle.load(f)
    
    ##       
    p_obj = pickle.loads(string)
    
    ## dbm
    ##   
    db = dbm.open("dbm","c")
    db[k1] = v1
    db.close()
    
    ##   
    db = dbm.open("dbm","c")
    for key in db.keys():
        print("key[%s] -- %s" % (key,db[key]))
    
    ## shelve
    import shelve
    db = shelve.open("persondb")    ## filename
    for object in [p1,p2]:
        db[object.name] = object
    db.close()  ##     
    
    ##  db     
    db = shelve.open("persondb")        ## db          ,    shelve         
    for key in db.keys():
        print("from db[%s]" % db[key])
    

    pythonリロード演算子
  • 二重下線の命名方法(__X__)は特殊なフック
  • である.
  • インスタンスが組み込み演算に現れると、このようなメソッドは
  • を自動的に呼び出す.
  • クラスは、多数の内蔵タイプの演算
  • をカバーすることができる.
  • 演算子の上書き方法はデフォルトではなく、
  • も必要ありません.
  • 演算子は、クラスをPythonのオブジェクトモデルアイテムと統合することができる
  • ##         ,                      
    class OverrideClass(ClassObject):
        def __init__(self,data):
            self.data = data
    
        def __add__(self, other):
            return OverrideClass(self.data + other)
    
        def __str__(self):
            return "[OverrideClass.data[%s]]" % self.data
    
        def mul(self,other):
            self.data *= other
            
    ##   
    t = OverrideClass("9090")     ##   __init__  
    t2 = t+"234"                  ##   __add__  ,         
    print t2                      ##   __str__  
    
    t2.mul(3)
    print(t2.data)
    

    python属性は検索を継承し、object.attribute
  • attributeで初めて現れるインスタンスオブジェクト
  • を特定する
  • 以降、オブジェクトの上にあるすべてのクラスは、__init__メソッドで定義された属性を持つattributeを検索し、下から上へ、左から右へ、継承検索ツリー
  • に属する.
  • 最後にオブジェクトのクラス属性を定義し、検索方法も下から上へ、左から右への遍歴検索
  • である.
    クラスツリーの作成
  • class文ごとに新しいクラスオブジェクト
  • が生成される
  • クラス呼び出しのたびに、新しいインスタンスオブジェクト
  • が生成される.
  • インスタンスオブジェクトは、インスタンスオブジェクトを作成するクラス
  • に自動的に接続される.
  • クラスをスーパークラスに接続する方法で、スーパークラスをクラスの頭括弧に列挙し、左から右の順序でツリーの順序
  • を決定する.
    class M1:
        def __init__(self):     ##       
            self.name = "m1 name"
            print("M1 class")
    
    class M2:
        def __init__(self):
            self.name = "m2 name"
            print("M2 class")
    
    class M3(M1,M2):
        pass
    
    class M4(M2,M1):
        pass
    
    #   :M3 M1 M2,      ,                    
    >>> a = M3()
    >>> print(a.name) 
    M1 class
    m1 name
    
    #   :M4 M2 M1
    >>> b = M4()
    >>> print(b.name)
    M2 class
    m2 name
    
    ## a.name     
    1.            ,              __init__  ,
    1.1    M3 -> M1 -> M2            __init__  
    1.2   __init__        name   ,         
    2.            ,              , M3 -> M1 -> M2   
    2.1         
    

    python OOPまとめ
  • インスタンスの作成--インスタンスのプロパティ
  • を入力します.
  • 動作方法--クラスメソッドに論理
  • をカプセル化する
  • 演算子リロード--外部から呼び出されたプログラムに独自の組み込み方法を提供するカスタマイズ動作
  • カスタム動作--サブクラスメソッドを再定義して、
  • を特殊化します.
  • カスタムコンストラクション関数--サブクラスにコンストラクションロジック特殊化
  • を追加