Pythonクラス名の先頭のアンダースコア 質問する

Pythonクラス名の先頭のアンダースコア 質問する

この質問はこの人は先ほど尋ねたそしてまたこれです、より微妙な点、具体的には「内部クラス」とは何を指すのか、という点に焦点を当てています。

私の状況は次のとおりです。私は MS Office ファイルを操作する Python ライブラリを構築していますが、そのクラスの多くは外部で構築されることを意図していませんが、そのメソッドの多くは API の重要な部分です。たとえば、次のようになります。

class _Slide(object):
    def add_shape(self):
        ...

_Slideは外部で構築されるべきではないため、ライブラリのエンドユーザーは を呼び出して新しいスライドを取得しますPresentation.add_slide()。ただし、スライドを取得したら、 を確実に呼び出せるようにする必要がありますadd_shape()。したがって、 メソッドは API の一部ですが、コンストラクターはそうではありません。Presentation クラスにのみ外部/API コンストラクターがあるため、この状況はライブラリ内で何十回も発生します。

PEP8 はこの点に関して曖昧で、「内部クラス」について言及していますが、内部クラスとして何が考慮されるかについては詳しく説明していません。この場合、クラスは「部分的に内部」であると言えると思います。

問題は、少なくとも 3 つの異なる状況を区別するための表記法が 2 つしかないことです。

  1. クラスのコンストラクターと「public/API」メソッドはすべて使用できます。
  2. コンストラクターは使用されませんが、クラスの「public/API」メソッドは使用されます。
  3. このクラスは実際には内部的なものであり、公開 API はなく、将来のリリースで変更または削除する権利を留保します。

コミュニケーションの観点から、外部 API (ライブラリのエンドユーザー層) と内部 API (開発者層) の明確な表現の間に矛盾があることに気付きました。エンドユーザーにとって、呼び出しは_Slide()禁止/自己責任です。ただし、これは内部 API の有効なメンバーであり、_random_helper_method()内部からのみ呼び出す必要があるものとは異なります_Slide()

この質問について、私に役立つような見解をお持ちですか? 慣例により、クラス名に「先頭に 1 つのアンダースコア」という武器を使用して、エンド ユーザー API の明確さを保つようにする必要がありますか? それとも、実装の詳細が変更される可能性があるため、クラス API が実際にはプライベートであり、たとえば、そのクラス API が存在するモジュールの外部のオブジェクトによって使用されないことを自分自身や他の開発者に伝えるために、それを留保しても問題ありませんか?


アップデート:数年にわたる熟考を経て、私はアクセスを意図していないクラスに名前を付ける際には先頭にアンダースコアを使用するという慣例に落ち着きました。クラスとしてモジュール (ファイル) の外部でアクセスします。このようなアクセスは通常、そのクラスのオブジェクトをインスタンス化したり、クラス メソッドにアクセスしたりするために使用されます。

これにより、モジュールのユーザー (多くの場合、もちろん自分自身 :) に、基本的な指標が提供されます。「先頭にアンダースコアがあるクラス名がインポート ステートメントに出現する場合、何かが間違っています。」(ユニット テスト モジュールはこのルールの例外であり、このようなインポートは「内部」クラスのユニット テストに頻繁に出現する可能性があります。)

これは、クラス. アクセス物体モジュールの外部で、おそらくファクトリなどによって提供されるクラス (型) の存在はまったく問題なく、おそらく期待されていることです。クラスとそこから作成されるオブジェクトを区別できないことが、私が最初に混乱した原因だと思います。

この規則には、ステートメントを作成するときにこれらのクラスを含めないという副次的な利点もありますfrom module import *。私は自分のコードでこれらを使用することはなく、使用を避けることをお勧めしますが、これらのクラス識別子はモジュール インターフェイスの一部となることを意図していないため、これは適切な動作です。

これは、何年も試行錯誤した結果得られた私の個人的な「ベストプラクティス」であり、もちろん「正しい」方法ではありません。結果は人によって異なる可能性があります。

ベストアンサー1

質問の説明だけではわかりませんでしたが、コメントで提供された追加情報から判断すると、クラスはSlide実際にはパブリックであると思われます。

add_slide()これは、インスタンスがメソッドの呼び出しによって間接的にのみ作成されるという事実にもかかわらず当てはまりますPresentation。呼び出し側はその後、インスタンスのメソッドを呼び出して操作することができるからです(そして、おそらくは呼び出すことが要求されます)。私の意見では、真にプライベートなクラスはのみそれを「所有」するクラスのメソッドによってアクセスできるようになります。

それ以外の方法では、カプセル化が壊れ、設計のコンポーネント間の結合が増加します。これらはどちらも望ましくないことであり、柔軟性と再利用性のために可能な限り回避する必要があります。

おすすめ記事