Python OOPオブジェクト向けプログラミング


参考:ダークホースプログラマーチュートリアル-Pythonベースオブジェクト向け
OOPの3つの特性があり、3つの特性には順序があります.
  • パッケージング
  • 継承
  • マルチステート
  • パッヶージ
    現実世界の事務を、プログラミングの対象にカプセル化し、抽象化することを指し、様々な属性と方法を含む.これは普通簡単なので、あまり話す必要はありません.
    唯一注意しなければならないのは、小さい頃から大きくパッケージ化し、クラスを開発することをお勧めします.たとえばこの2つのクラスは、弾丸のすべての属性と方法を定義し、開発してから、上の層のピストルを開発する必要があります.これなら便利です.逆にピストルを開発するのに適していて、半分まで書けないと弾丸のところに書くので、散らかっていることに気づきました.
    継承
    子クラスは、親クラスと親クラスのすべての属性、メソッドを継承できます.
    フォーマットの継承:
    class Parent:
        def func1(self):
            pass
    
    class Son(Parent):
        def func2(self):
            func1()

    メソッド書き換え:子クラスが気に入らない場合は、自分の親クラスの属性、メソッドを書き換えることもできます.2つのケースがあります.
  • Overwrite上書き親メソッド:同じ名前の関数を1つ書くだけで上書きできます.
  • Extend拡張親関数:
  • 第1の方法(主):同じ名前の関数を書き、super().func()で親メソッドを参照します.superはpython builtin特殊クラスで、super()はsuperのインスタンスを生成します.サブクラスでsuperインスタンスを生成すると、親の参照が得られます.
  • 第2の方法(python 2.x以前に使用):同じ名前の関数を書き、ParentName.func(self)で親メソッドを参照します.ただし、親名が変更されるとすべての子が変更されるため、推奨されません.

  • ≪プライベート・継承なし|Private Inheritute|emdw≫:サブクラスが継承できるのは、親の公開コンテンツのみですが、親のプライベート・コンテンツは含まれません.アクセスする場合も可能ですが、間接的に親を呼び出してメソッドでプライベート・コンテンツを呼び出す必要があります.
    マルチ継承
    Pythonでは、子クラスは複数の親を同時に持つことができます.つまり、複数の親のすべての属性、メソッドを同時に継承することができます.
    フォーマットの継承:
    class Father:
        def func1(self):
            pass
    
    class Mother:
        def func2(self):
            pass
    
    class Son(Father, Mother):
        def func3(self):
            func1()
            func2()

    注:複数の親の間に同じ名前のメソッドがある場合は、最初の親のメソッドが継承されます.MRO, Method Resolution Order
    継承順序の表示:クラスが持つ.__mro__属性(MRO, Method Resolution Order)によって、このクラスの継承順序を表示できます.
    サブクラスは、親関数を呼び出すためにFatherName.func()を直接書くことができます.しかし、サブクラスがsuper().func()を使用すると、pythonはMROの順序に従って、近くから遠くまで逐次探し、最近の上司を見つけたら返します.
    上記の例では,マルチ継承であれば,SON -> Father -> Mother -> objectが探索順序である.
    クラスの組み込み属性とメソッドを表示します.dir(className)すべての属性メソッドが組み込まれていることを確認できます.
    Python内蔵objectベースクラス
    Python 3は新式のクラス定義を使用し始めた.すなわち、デフォルトではすべての定義のクラスが自動的にobjectという組み込み基礎クラスを継承する.object基礎クラスは便利な属性を多く定義している.18項目の多さを含む.旧式のPython 2.x時代は、object基礎クラスを継承せず、自己定義のクラスは__doc____module__の2つの組み込み属性のみであった.2.x時代、手動で継承する必要がある場合は、次のようにします.
    class MyClass(object):
        pass

    マルチステート
    マルチステートとは、異なるサブクラスオブジェクトが同じ親メソッドを呼び出すと、マルチステートの多様な結果を生成するプログラミング特性を指します.マルチステートの前提は、親メソッドを継承し、親メソッドを書き換えることができます.
    マルチステートの特徴:
  • は、クラスの内部設計
  • に影響を及ぼさずにメソッドを呼び出すテクニックです.
  • コード柔軟性の向上
  • def Father():
        def work(self):
            do_job()
         
        def do_job(self):
            print('Farming on the field...')
    
    
    def Son(Father):
        def do_job(self):
            print('Programming at an office...')
    
    # ---- Now let's work ----
    Jason = Son()
    Jason.work()

    以上のコードでは、同じwork()関数であり、かつdo_work()が必要である.ただし、異なる人が呼び出すのは異なるdo_workである.Fatherは自分のdo_workを呼び出し、息子は自分でdo_workを書き直したので、自分の方法を呼び出す.これがマルチステートである--継承された方法であり、誰がどんな方法を使うかを特別に指定する必要はなく、オブジェクトは自分に合った方法を自動的に呼び出す方法.
    クラスとインスタンス
    Pythonでは、インスタンスはオブジェクトであり、クラスもオブジェクトであり、すべてがオブジェクトである.しかし、これもPython OOPで多くのトラブルを引き起こす原因である.
    実例の対象はとてもよく理解して、使って、直接使って、言わないでください.しかし はそんなによく理解しません.
    簡単に言えば、 も標準的なオブジェクトであり、独自の属性と方法があり、 のように複数のインスタンスオブジェクトを生成できるにすぎない.クラスオブジェクトにはこの2つの大きな研究点がある.
  • クラスプロパティ:すべてのインスタンスをアクセスおよび操作できる公衆トイレ
  • クラス属性の定義:classのすべてのメソッドの外
  • アクセスクラス属性:className.propertyName
  • クラスメソッド:分かりにくいですが、@classmethodという装飾器を使用する必要があります.関数の最初のパラメータは、clsのようにキーワードselfでなければなりません.
  • @classmethodデザイナ:インスタンスメソッドではなく、解釈器に であることを伝えるために使用されます.
  • clsパラメータ:

  • クラス属性とインスタンス属性
    これはPython OOPの中で多くの人を悩ませている特徴です.しかし、実は理解しにくくありません.まとめは以下の通りです.
    class MyClass:
        #         ,    。==        “    ”
        #              ,           
        count = 0
        
        def __init__(self):
            #  self.   ,     ,             ,selfish
            self.name = "Jason"

    クラスのプロパティにアクセスする方法は2つあります.
  • ClassName.propertyName:クラス名で直接クラス属性にアクセスすることを推奨します.
  • Instance.propertyName:クラス属性にインスタンス名でアクセスすることは推奨されません.書き込み操作が必要な場合、この方法はクラス属性に影響を与えることなく、自分にインスタンス属性を追加するだけです.
  • クラス属性の動的追加
    方法1:
    >>> MyClass.newAttribute = 'I am a class attribute'
    >>> print( MyClass.newAttribute )
    'I am a class attribute'

    方法2:装飾器
    # Customized decorator for classproperty
    class classproperty(object):
        def __init__(self, getter):
            self.getter= getter
        def __get__(self, instance, owner):
            return self.getter(owner)
    
    class MyClass:
        @classproperty
        def newAttribute(cls):
            return 'I am a class attribute.'
    
    >>> print( MyClass.newAttribute )
    'I am a class attribute'

    メソッドをクラス属性にカプセル化するのは、他のクラス属性に基づいてクラス属性をカスタマイズする必要がある場合があります.一般的には、クラス属性定義時に現在のクラスまたはクラス内の他の属性を取得することはできません.
    クラスメソッド
    クラスメソッドはクラスプロパティのようなもので、全クラスに属するメソッドですが、(推奨)クラスプロパティにアクセスするためにのみ使用されます.
    クラスメソッド:理解しにくいですが、@classmethodという装飾器を使用する必要があります.関数の最初のパラメータは、clsのようにキーワードselfでなければなりません.
  • @classmethodデザイナ:インスタンスメソッドではなく、解釈器に であることを伝えるために使用されます.
  • clsパラメータ:selfのように、現在のクラスを指す.
  • 注意:@classmethodclsはいずれもキーワードであり、変更できません.
    コード:
    class MyClass:
        #     “   ”
        count = 0
        
        #       “   ”
        @classmethod
        def func(cls):
            print(cls.count)

    クラス静的メソッド
    クラス内のstaticmethodアクセラレータはpythonベースクラスobjectのパッケージ、装飾のための方法です.クラスメソッドの前にアクセラレータ@staticmethodを置くと、メソッドは に変換されます.静的メソッドは、インスタンスの情報にもクラスの情報にもアクセスしない非常に独立した方法です.
    コード:
    class MyClass:
        #     “   ”
        count = 0
        
        #       “   ”
        @staticmethod
        def func():
            pass

    プロパティ属性
    クラス中のpropertyデザイナは、pythonベースクラスobjectのパッケージ、デザイナのための方法でもあります.クラスメソッドの前にデザイナ@propertyを置くと、メソッドは に変換されます.多くの場合、メソッドをプロパティに偽装するのは便利です.
    class MyClass:
        #             “   ”
        @property
        def name(self):
            return "Jason"
    
    c = MyClass()
    print( c.name )

    objectベースクラスを継承する場合、pythonは3つの操作に対応する3つの属性装飾を与えます.
  • 読み込み:@property
  • 書き込み:@name.setter
  • 削除:@name.deleter
  • すなわち、クラス属性my_nameを読み出すと、@propertyで修飾されたメソッドが呼び出され、my_nameを変更すると、@my_name.setterで修飾されたメソッドが呼び出され、この属性を削除すると、@my_name.deleterで修飾されたメソッドが呼び出されます.
    注意:
  • うち@property,@*.setter,@*.deleter,これは固定された名前で、変更できません.
  • 3つの操作で修飾された3つの関数は、同じ名前である「クラス属性」名でなければなりません.
  • コード:
    class MyClass:
        #             “   ”
        @property
        def name(self):
            return "Jason"
    
        @name.setter
        def name(self, value):
            self.name = value
    
        @name.deleter
        def name(self):
            del "Jason"
    
    c = MyClass()
    
    print( c.name )  # READ
    c.name = "Brown"  # SET
    del c.name  # DELETE

    propertyプロパティの適用
    多くのOOP言語、property に対して、一般的な操作は:1つのプライベート属性で、2つの公有方法に協力します.例えば:
    class MyClass:
        def __init__(self):
            self.__name = "Jason"
    
        def get_name(self):
            return self.__name
    
        def set_name(self, value):
            self.__name = value
    
    c = MyClass()
    
    #     
    c.set_name("Brownee")
    print( c.get_name() )

    Pythonでは、装飾器を利用して以下のコードに変更することができ、呼び出しのプロセスを極めて便利にすることができます.
    class MyClass:
        def __init__(self):
            self.__name = "Jason"
    
        @property
        def name(self):
            return self.__name
    
        @name.setter
        def name(self, value):
            self.__name = value
    
    c = MyClass()
    
    #     
    c.name = "Brownee"
    print( c.name )