2016-05-16 5 views
2

2つの異なるファイルからgit(gitpython)リポジトリを使いたいという問題があります。しかし、私はそれを一度しか複製せずにモジュール間でオブジェクトを共有する賢明な方法を考え出すことはできません。レポはかなり大きいので、オブジェクトにアクセスする必要があるたびにそれらを複製するのは最適ではありません。gitリポジトリを複製して別の場所にオブジェクトをインポート

私は、utils.pyというファイルにクラスとそのインスタンスを作成しようとしました。しかし、utils.pyのクラスの__init__で起こるはずですが、私がそれらをインポートすると、レポがクローン化されたようには見えません。確かにこれは、インポート時にハングするのを防ぐためのPythonの保護手段でなければなりません。

私はdictをサブクラス化しようとしましたが、まだアクセスしていないにもかかわらずそれが動作しなかった場合は、__getattr__を使用してクローンを作成しました。それはちょうどインポートされたように思えましたが、前と同じようにクローニングをスキップしました。

これは私が他の場所でそれをインポートできるようにutils.pyに定義するために必要なものです:

compiler_repo = git.Repo.clone_from(someurl, somepath)

答えて

1

コードのinitには、他のどのように実行されるだけでPythonコードです。無限ループまたはブロッキング待機をその中に置くと、実際にインポートがハングアップする可能性があります。

高価な初期化コードをアプリケーションから呼び出される関数に置くことで、ライブラリの起動時間を最小限に抑えることができます。実行する作業の量は変更されませんが、少なくとも作業のタイミングはアプリケーションの制御下にあり、何が間違っているのかを簡単に把握することができます(のコードは難しいデバッグ)。

初期化手順を非表示にする方法はさまざまです。たとえば、遅延ローダーを持つクラスを定義することができます。

class RepoLoader: 
    def __init__(self, url, path): 
     self.url = url 
     self.path = path 
     self._repo = None 

    def fetch_repo(self): 
     self._repo = git.Repo.clone_from(self.url, self.path) 

    @property 
    def repo(self): 
     if self._repo is None: 
      self.fetch_repo() 
     return self._repo 

compiler = RepoLoader(someurl, somepath) 

他の場所であなたのパッケージでは、使用してレポを求めることができます:

from . import utils 
compiler_repo = utils.compiler.repo 

今すぐパッケージのユーザは、ANとしてutils.compiler.fetch_repo()を呼び出すことができます発生するタイミングを制御したい場合や、アプリケーションに任せることができる場合は、初期化ステップを実行します。もう少し作業すれば、fetch_repoを別のスレッドに入れて、アプリケーションの初期化を進めることができ、コードでリポジトリが必要なときだけブロックすることができます。

関連する問題