一般的に、標準的なOOPの状況では、経験則では、必要に応じてアクセスを最小限に抑えてクラスを作成します。つまり、必要なものだけを公開し、必要なものだけを保護するなどです。 。(例外があり、私が説明していることが常に当てはまるわけではありません。FWIW、「必要に応じて最小限のアクセス」という考え方は、より標準的なOO C++/Javaの状況で役立ちます。)
ただし、Pythonでは、public
、protected
、private
などの厳密なアクセス修飾子はありません。Pythonには疑似protected
と疑似private
は、オブジェクトフィールドとメソッドにシングル_
とダブル__
のアンダースコアを付けます。
より「正規のOO」[1] Pythonの状況では、デフォルトのアクセス修飾子の経験則は何ですか?
より多くを制限し(C++/Javaのように)、すべてのフィールド/メソッドを__
で修飾するのは、要件/設計/ APIでpublic
またはprotected
?
または、経験則では、すべてのpythonフィールド/メソッドをpublic
として開始し、必要に応じて制限しますか?
デフォルトで_
を使用してprotected
を設定し、pylint
を使用してカプセル化の破損を検出する人を見かけました。デフォルトでprivate
になる他の人も見ることができます。そして、デフォルトでpublic
になっている人もまだいると思います。
[1]私は「標準的なOO」という用語を使用して、教科書と呼ぶものの多くを指しますOOプログラミング理論/状況。私の経験では、実際のプログラミングは教科書とは異なることがよくありますOOまたは正規OOプログラミング理論。
まず、二重アンダースコア(dunderと呼ばれることもあります)は、非公開を意味するのではなく、特定の競合を回避するための名前マングリング戦略を意味します。チェック このレイモンドヘッティンガーの講演 (Pythonコア開発者の1人...そして講演全体は時間を割く価値があります)。ダンダー/名前のマングリング。
したがって、問題は、1つのアンダースコアを使用して「保護」するタイミングと、保護しないタイミングについてです。これに関する私の経験則は、物事をできるだけプライベートでシンプルに保つことです。
現時点では、材料と重量の属性のみを持つStone
クラスがあるとします。レシピは次のようになります。
デフォルトではすべてに下線が引かれます:_weight
および_material
クラスAPIについて慎重に検討し、次の質問に答えてください:どのメンバーを公開するのですか?。次に、アンダースコアを削除して、これらのメンバーをパブリックに変換します。 _weight
がweight
に変換されるとしましょう
時間が経つにつれ、あなたは「すべきではない」メンバーを完全なパブリックメンバーに変換する必要があるかもしれません。恥ずかしいことではありません。アンダースコアを削除し、クラスコードをリファクタリングして新しい名前に一致させます。 _material
> material
。以前の属性にアクセスするために@property
を作成しないでください。これはより複雑です。
繰り返しますが、時間が経つにつれて、属性の1つが別の属性に依存するようになる可能性があります。weight
がvolume
およびdensity
に依存するとしますが、心配しないでください。今度はweight
属性を@property
に変換し、既存のコードを壊すことなく単一の真のソースを保持する時です。