Python学習ノート(2)OOPプログラミング

5697 ワード

中国語学習サイト:廖雪峰の公式サイトhttps://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
2.OOPオブジェクト向けプログラミング
クラスのアクセス制限
  • classの二重下線で始まる変数(例えば、_private_val)はプライベート変数であり、外部から直接アクセスすることはできないが、二重下線で始まる変数と終わる変数を除く(例えば_name)特殊変数であり、外部から直接アクセスできる
  • .
  • プライベート変数の実現原理はpython解釈器がプライベート変数を_Classname__private_val.だから直接アクセスすればClassname__private_valはアクセスできますが、異なるバージョンのPython解釈器が__をprivate_valを異なる変数名に変更します.
  • しかし直接a__を用いるprivate_val=1で、この付与は通過できますが、注意:これは__という名前で新規作成されました.private_valのメンバー変数は、元のプライベート変数ではありません(すでに_Classname__private_valと改名されています)
  • _slots_ クラスに追加できる属性を制限する.
  • .
    class Student(object):
        __slots__ = ('name', 'age') #  tuple           
    >>> s.age = 25 #     'age'
    >>> s.score = 99 #     'score'
    Traceback (most recent call last):
      File "", line 1, in 
    AttributeError: 'Student' object has no attribute 'score'
    

    注意:slots_定義されたプロパティは、現在のクラスインスタンスにのみ機能し、継承されたサブクラスには機能しません.
    インスタンスへのバインド方法
  • は通常、直接クラスにメソッドを追加しますが、pythonはインスタンスバインドのみのメソッド
  • をサポートします.
    >>> def set_age(self, age): #             
    ...     self.age = age
    ...
    >>> from types import MethodType
    >>> s.set_age = MethodType(set_age, s) #          
    >>> s.set_age(25) #       
    >>> s.age #     
    25
    
  • インスタンス属性は現在のインスタンスにのみ有効であり、クラス属性はクラスとすべてのクラスのインスタンスに対して
  • 有効である.
    @propertyデコレーション
  • リードインタフェース用@property装飾、ライトインタフェース用@score.setter装飾、scoreは装飾が必要なインタフェース名である.
  • は関数であるにもかかわらず、呼び出し時にカッコを付けずに変数としてアクセスする.書き込みインタフェースが定義されていない場合、この「変数」は読み取り専用で書き込み不可である.
  • 注意:書き込みインタフェースを定義するには@propertyを定義する必要があります.
  • class Student(object):
        #get  
        @property
        def score(self):
            return self._score
        #set  
        @score.setter
        def score(self, value):
            if not isinstance(value, int):
                raise ValueError('score must be an integer!')
            if value < 0 or value > 100:
                raise ValueError('score must between 0 ~ 100!')
            self._score = value
    
    >>> s = Student()
    >>> s.score = 60 # OK,     s.set_score(60)
    >>> s.score # OK,     s.get_score()
    60
    >>> s.score = 9999
    Traceback (most recent call last):
      ...
    ValueError: score must between 0 ~ 100!
    

    インスタンス属性とクラス属性の違い
    インスタンス属性はクラスで定義され、クラスまたはインスタンスでアクセスできますが、インスタンスに同名の属性をバインドすると、インスタンス属性はクラス属性を上書きします.次の例では、s.name='Michael'を呼び出すと、sには同じ名前のnameプロパティが2つあります.1つはクラスタイプ(「Studio」)で、1つはインスタンスプロパティ(「Michael」)で、インスタンスプロパティは削除されるまでクラスプロパティを上書きします.
    >>> class Student(object):
    ...     name = 'Student'
    ...
    >>> s = Student() #     s
    >>> print(s.name) #   name  ,       name  ,       class name  
    Student
    >>> print(Student.name) #     name  
    Student
    >>> s.name = 'Michael' #      name  
    >>> print(s.name) #               ,  ,       name  
    Michael
    >>> print(Student.name) #          , Student.name      
    Student
    >>> del s.name #        name  
    >>> print(s.name) #     s.name,     name      ,  name        
    Student
    

    バインド方法と_slots_
    インスタンスにメソッドをバインドします.注意:
  • バインドインスタンスメソッドは、オブジェクトインスタンスをインポートする必要があるため、関数割り当てを直接行うことはできません.
  • さらに、インスタンスメソッドは単一のインスタンスにのみ機能する.
  • >>> def set_age(self, age): #             
    ...     self.age = age
    ...
    >>> from types import MethodType
    >>> s.set_age = MethodType(set_age, s) #          
    

    クラスへのバインド方法:直接値を割り当てますが、関数の最初のパラメータはselfでなければなりません.
  • クラスバインドメソッドは、すべてのインスタンスに対して機能し、再インスタンス化を必要とせず、以前に作成したインスタンスも
  • として機能する.
    >>> def set_score(self, score):
    ...     self.score = score
    ...
    >>> Student.set_score = set_score
    

    使用_slots_変数とメソッドを含むインスタンスの追加プロパティを制限できます.
    クラス内の特殊な関数
  • _init_:クラスの初期化関数/構築関数
  • _slot_:制限クラスおよびそのインスタンスの追加可能な属性
  • _len_: 長さを返し、len()関数をサポートし、オブジェクトを自動的に呼び出す_len_()メソッド
  • _str_: print()インスタンスの場合、関数
  • が呼び出されます.
  • _repr_:直接表示変数はこの関数を呼び出し、デバッグサービスの
  • である.
    s = Student()
    print(s) #  __str__
    s  #  __repr__
    
  • _iter_: クラスがfor...inループに使用されたい場合、listやtupleのように_を実現する必要があります.iter_()メソッド、このメソッドは反復オブジェクトを返し、Pythonのforループは反復オブジェクトの_を呼び出し続けます.next_()メソッドは、StopIterationエラーが発生したときにループを終了するまで、ループの次の値を取得します.
  • class Fib(object):
        def __init__(self):
            self.a, self.b = 0, 1 #         a,b
    
        def __iter__(self):
            return self #           ,     
    
        def __next__(self):
            self.a, self.b = self.b, self.a + self.b #       
            if self.a > 100000: #        
                raise StopIteration()
            return self.a #       
    
    >>> for n in Fib():
    ...     print(n)
    ...
    1
    1
    2
    3
    5
    ...
    46368
    75025
    
  • _getitem_: listをサポートするように、要素
  • を下付きで取り出す.
    class Fib(object):
        def __getitem__(self, n):
            a, b = 1, 1
            for x in range(n):
                a, b = b, a + b
            return a
    >>> f = Fib()
    >>> f[0]
    1
    
  • _getattr_: オブジェクトのプロパティを呼び出すときに、プロパティが見つからない場合は、関数が呼び出されます.
  • _call_: インスタンス化メソッドをサポートし、インスタンス呼び出しメソッド
  • を直接使用する
    class Student(object):
        def __init__(self, name):
            self.name = name
    
        def __call__(self):
            print('My name is %s.' % self.name)
            
    >>> s = Student('Michael')
    >>> s() # self      ,   s.__call__()
    My name is Michael.
    
    >>> callable(Student())
    True
    

    callable()関数を使用すると、オブジェクトが「呼び出し可能」オブジェクトであるかどうかを判断できます.