3

私たちは、非公開にしたいいくつかの独自のアルゴリズムと機密性の高いロジックを使用して、Python で新しいプロジェクトを開始しています。また、コードに取り組んでいる数人の部外者 (一般の一部のメンバー) も参加します。部外者にコードの小さなプライベート ビットへのアクセスを許可することはできませんが、パブリック バージョンが十分に機能することを望んでいます。

私たちのプロジェクト Foo には、bar1 つの関数 を持つモジュール があるとしますget_sauce()。で実際に何が起こるかget_sauce()は秘密ですが、 の公開バージョンがget_sauce()、間違っていても許容できる結果を返すことを望んでいます。

また、独自の Subversion サーバーを実行しているため、誰が何にアクセスできるかを完全に制御できます。

シンボリックリンク

私が最初に考えたのはシンボリック リンクでしbar.pyた。残念ながら、シンボリック リンクの作成は面倒な手作業です。特に、これらのプライベート モジュールが実際に 20 個ほどになる場合はなおさらです。bar_public.pybar_private.py

さらに重要なことに、Subversion authz ファイルの管理が難しくなります。これは、保護したいモジュールごとに例外をサーバーに追加する必要があるためです。誰かがこれを行うのを忘れて、誤ってシークレットをチェックインする可能性があります...その後、モジュールはリポジトリにあり、それなしでリポジトリを再構築する必要があり、その間に部外者がそれをダウンロードしないことを願っています.

複数のリポジトリ

次に考えたのは、2 つのリポジトリを用意することでした。

private
└── trunk/
    ├── __init__.py
    └── foo/
        ├── __init__.py
        └── bar.py
public
└── trunk/
    ├── __init__.py
    └── foo/
        ├── __init__.py
        ├── bar.py
        ├── baz.py
        └── quux.py

private/内部開発者だけが と の両方をチェックアウトできるようにするという考え方ですpublic/。社内の開発者は自分の を設定しPYTHONPATH=private/trunk:public/trunkますが、それ以外の人は を設定するだけですPYTHONPATH=public/trunk。そうすれば、インサイダーとアウトサイダーの両方from foo import barが適切なモジュールを取得できますよね?

これを試してみましょう:

% PYTHONPATH=private/trunk:public/trunk python
Python 2.5.1
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo.bar
>>> foo.bar.sauce()
'a private bar'
>>> import foo.quux
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named quux

私は Python の専門家ではありませんが、Python はモジュールfooとそれに関連する検索についてすでに決心しているようです。

>>> foo
<module 'foo' from '/path/to/private/trunk/foo/__init__.py'>

削除しても役に立ちませんfoo

>>> import sys
>>> del foo
>>> del sys.modules['foo']
>>> import foo.quux
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named quux

より良い解決策や提案を教えていただけますか?

4

3 に答える 3

3

パッケージの__init__メソッドで、他のディレクトリにあるモジュールを探すように変更できます。foo__path__

という名前のディレクトリを作成secretし、プライベート Subversion リポジトリに配置します。secret独自bar.pyの. __init__.py公開fooパッケージの に次のようなものを入れます:

__path__.insert(0,'secret')

これは、プライベート リポジトリを持っているユーザーを意味するため、検索パスの最初のディレクトリと同様にsecret、独自のディレクトリを取得します。他のユーザーの場合、Python は を見つけられず、 の次のディレクトリとして検索されるため、通常のからをロードします。bar.pyfoo.barsecretsecret__path__bar.pyfoo

したがって、次のようになります。

   private
    └── trunk/
        └── secret/
            └── bar.py
    public
    └── trunk/
        ├── __init__.py
        └── foo/
            ├── __init__.py
            ├── bar.py
            ├── baz.py
            └── quux.py
于 2009-09-18T08:36:49.753 に答える
2

ある種のプラグイン システムを使用し、プラグインを自分のものにしておきますが、オープン コードで出荷される公開プラグインも用意してください。

プラグインシステムはたくさんあります。シンプルなものは自分で簡単に作ることができます。より高度なものが必要な場合は、Zope コンポーネント アーキテクチャを好みますが、setuptools entry_points などのオプションもあります。

あなたのケースでどちらを使用するかは、2番目の質問として適切です。

于 2009-09-18T08:44:21.637 に答える
0

Flaskのドキュメントを読んでいるときに気付いた代替ソリューションを次に示します。

flaskext/__init__.py

このファイルの唯一の目的は、パッケージを名前空間パッケージとしてマークすることです。これは、異なる PyPI パッケージの複数のモジュールを同じ Python パッケージに配置できるようにするために必要です。

__import__('pkg_resources').declare_namespace(__name__)

そこで何が起こっているのかを正確に知りたい場合は、これがどのように機能するかを説明しているdistributeまたはsetuptoolsのドキュメントをチェックアウトしてください。

于 2010-07-07T07:19:03.420 に答える