Pythonの私有属性と保護された属性原理解析

1787 ワード

前言:
PythonはJavaのようにprvateと protected修飾子はプライベート属性と保護された属性を作成しますが、Pythonには簡単な機構があり、サブクラスの予期せぬ「プライベート」属性のカバーを避けることができます。
まずDugクラスを定義します。
class Dog:
    'Dog class'
    def __init__(self, age, sex, mood):
        self.age = age
        self._sex = sex
        self.__mood = mood
 
一、保護された属性:
Pythonには、属性名の前に1つの下線(_属性名)を付けて保護された属性を表しているデフォルトの規定があります。Python解釈器は、1つの下線プレフィックスを使用する属性名を特殊な処理はしませんが、プログラマたちはこの約束を厳格に守り、クラスの外部ではこのような属性にアクセスしません。
dog = Dog(3, 'male', 'happy')
print(dog._sex)                # male
dog._sex = 'female'
print(dog._sex)                # female

単一のアンダーラインプレフィックスがある属性については、Pythonインタプリタが特別な処理をしないため、アクセスおよび直接修正が可能であることが分かる。
 
二、プライベート属性:
2つの下線プレフィックスの属性(2つのプリアンブル下線、尾部に1つの下線がないまたは最大である)を使用して私有属性と呼び、Pythonはこの属性を先に特殊処理します。属性名の前に下線と類名を付けます。プロパティ名をインスタンスの__u uに保存します。dict_.を選択します
dog = Dog(3, 'male', 'happy')
print(dog.__dict__)              # {'age': 3, '_sex': 'male', '_Dog__mood': 'happy'}
print(dog.__mood)                # AttributeError: 'Dog' object has no attribute '__mood'
このような属性は直接アクセスできません。属性名の前に下線とクラス名を付けた特殊な処理が行われています。
ただし、先にこの属性を修正すれば、次のようにアクセスできます。その理由はこの実例が__u u uという名前に結び付けられているからです。moodの属性は、元の_にあります。Dug_.moodは衝突していません
dog = Dog(3, 'male', 'happy')
print(dog.__dict__)              # {'age': 3, '_sex': 'male', '_Dog__mood': 'happy'}
dog.__mood = 'female'
print(dog.__mood)                # female
print(dog.__dict__)              # {'age': 3, '_sex': 'male', '_Dog__mood': 'happy', '__mood': 'female'}