web-dev-qa-db-ja.com

Python:パッケージ内の「プライベート」モジュール

モジュールmod_amod_bを含むパッケージmypackがあります。パッケージ自体とmod_aを自由にインポートするつもりです。

import mypack
import mypack.mod_a

ただし、mypack専用にmod_bを保持したいと思います。これは、後者の内部コードを整理するためだけに存在するためです。

私の最初の質問は、Pythonプログラミングでこのような「プライベート」モジュールを持つことは受け入れられている慣行ですか?

はいの場合、私の2番目の質問は、この意図をクライアントに伝えるための最良の方法は何ですか?名前の前にアンダースコア(つまり、_mod_b)を付けますか?または、サブパッケージprivateを宣言し、そのようなすべてのモジュールをそこに配置することをお勧めしますか?

38

私が決めた解決策は、サブパッケージ「private」を作成し、そこに隠したいすべてのモジュールを配置することです。このようにして、それらは収納されたままになり、mypackのモジュールリストがよりクリーンになり、解析しやすくなります。

私には、これも非Pythonのようには見えません。

14

プライベートモジュールの前にアンダースコアを付けて、ユーザーに意図を伝えます。あなたの場合、これはmypack._mod_b

これは、Pythonモジュール;つまり、_socketおよびsocket

39
Jeremy

明示的なプライベートキーワードはありませんが、プライベート関数を単一のアンダースコアで開始する規則がありますが、先頭に2つのアンダースコアを付けると、他の人がモジュールの外部から関数を簡単に呼び出すことができなくなります。 PEP 8 から以下を参照してください

- _single_leading_underscore: weak "internal use" indicator.  E.g. "from M
  import *" does not import objects whose name starts with an underscore.

- single_trailing_underscore_: used by convention to avoid conflicts with
  Python keyword, e.g.

  Tkinter.Toplevel(master, class_='ClassName')

- __double_leading_underscore: when naming a class attribute, invokes name
  mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).

- __double_leading_and_trailing_underscore__: "magic" objects or
  attributes that live in user-controlled namespaces.  E.g. __init__,
  __import__ or __file__.  Never invent such names; only use them
  as documented.

モジュール全体をプライベートにするには、モジュールを含めないでください__init__.pyファイル。

6
aterrel

Pythonは、「プライベート」または「保護された」メソッドまたはクラスを厳密に認識またはサポートしていません。単一のアンダースコアが前に付いたメソッドは公式APIの一部ではないという慣習がありますが、クラスやファイルではこれを行いません-醜いです。

誰かが本当にmod_bをサブクラス化またはアクセスする必要がある場合、なぜその人がそうするのを防ぐのですか?ドキュメントに優先APIを指定し、モジュールにドキュメントを指定して、直接アクセスして代わりにmypackを使用しないでください。

1

このシナリオで注意すべきことの1つは、間接インポートです。 mypackの場合

from mypack._mod_b import foo
foo()

その後、ユーザーはできます

from mypack import foo
foo()

そして、賢くはありません。としてインポートすることをお勧めします

from mypack import _mod_b
_mod_b.foo()

その後、ユーザーがしようとするとすぐに赤い旗が表示されます

from mypack import _mod_b

実際のディレクトリ構造については、Jeremyの回答を_package_of_this_kindパッケージに拡張することもできます。このパッケージには、好きな「アクセス修飾子」を含めることができます。ユーザーはドラゴンがいることを知っています。

0
Joel B