2

私の人生の間、私はPythonの移行が非常に苛立たしいことに気づいています。私がやろうとしていることの1つは、構成ディクショナリからクラスの単一インスタンスを初期化してから、他のモジュールでそのクラスにアクセスすることです。

私が直面している問題/私が取ったアプローチはうまくいかず、誰かが正しい「pythonic」アプローチで操縦できることを望んでいます。

まず、私のアプリは、ツイストプラグインの一部として、またはスタンドアロンスクリプトとして初期化できます。

import resource
class App(object):
  _config = None
  _someotherobject = None
  def __init__(self, config):
    self._config = config
    ....

def main():
  global myapp
  myapp = App({}) # Could use help here, how to pass config to it

myapp = None #Global doesnt work as I expect, it doesnt modify this instance, stays as None
if __name__ == '__main__':
  main()


#-----------resource.py
class Foo(object):
  def foo(self):
    app.myapp.somefunction() #NoneType object has no attribute

他のモジュールのコードが開始される前に、アプリオブジェクトが作成されていることを確認しました。モジュール内の「グローバル」インスタンスが実際に期待どおりに機能しない理由がわかりません。また、別のモジュールからインスタンスを参照する方法についても混乱しています。

-----編集------いくつかのポイントを明確にするために、スクリプトはpython app.py app.pyで呼び出されresources.py、クラス定義の束であると呼ばれるモジュールを参照します。一部のクラスでは、実行時に、app.myappの「シングルトン」インスタンスを参照します。

4

3 に答える 3

3

別のモジュールからインポートmainされた場合ではなく、スタンドアロン スクリプトとしてのみ呼び出されます。

if __name__ == '__main__':
  main()

コマンドラインからモジュールを実行可能にするためのトリックです。

それを証明するために

import app
app.main()

次に、コードを実行します。

初期化するappとシングルトンのようになり、それをインポートする他のモジュールはその初期化されたバージョンを取得します。

アクセスしたくないappが、モジュールが同じデータを言いapp = MyApp()、共有できるようにしたいという同様の問題がありました(なぜそれが必要だったか忘れましたが、最初の使用時に初期化する必要があったのかもしれません)

シングルトンの代わりにボーグを使用することになりました。

于 2013-02-19T21:10:04.013 に答える
0

あなたの最大の問題は sotapme によって言及されたものです。トップレベル スクリプトとして実際に実行しない場合はapp.py、 を呼び出すコードがないapp.main()ため、グローバルを初期化するものは何もありません。

それを超えて、「別のモジュールからインスタンスを参照する方法」は、簡単なことを1つ知っていれば非常に簡単です。

Python では、グローバルは名前空間です。

より具体的に言えば、他のモジュールでは、単にimport app、グローバルに としてアクセスしますapp.myapp

__name__ == '__main__'sotapme が説明したように、トリックを使用すると、毎回関数import appを実行することなく、何度でも実行できることを意味します。main()

特に、これを実行すると:

python app.py

Python インタープリターはapp.py__name__設定された状態でロードされる'__main__'ため、ifステートメントがトリガーされ、(モジュールレベルの) グローバル変数myappが に設定されApp({})ます。

ここで、resource.pyがになるとimport app__name__が に設定されるappため、ifステートメントはトリガーされないAppため、新しいものを作成してグローバルを置き換えます。のコードからresource.pyを使用でき、 のコードが と見なすapp.myappのと同じオブジェクトにアクセスします。app.pymyapp


Appまた、構成をコンストラクターに渡すためのヘルプも求めます。ここであなたの問題が何であるかわかりません。構成として空のものを渡していますdictdict渡すものが違う場合は、それを使用してください。これの代わりに:

myapp = App({}) # Could use help here, how to pass config to it

これを行う:

myapp = App(configdict)

問題がそれを取得する方法を知っている場合configdict、それは情報がどこから来たかによって異なります。

ユーザーが編集可能な構成ファイルを解析しようとしている場合、configparserモジュールは従来の .ini スタイルのファイルに対して正常に機能し、ドキュメントには他の一般的な形式の処理方法を説明するリンクがあります。

コマンド ラインから構成情報を作成しようとしている場合は、 を参照してくださいargparse

環境変数が上記のいずれかと対話できるようにする場合 (たとえば、 aMYAPP_CONFIGconfigparserコードに通常とは異なる構成ファイルをロードするように指示したり、が のコマンドライン引数にMYAPP_CACHE_DIR異なるデフォルトを提供したりする場合)、次のようになります。の値を使用できますが、それらを操作するには独自のコードを作成する必要があります。--cachedirargparseos.environ

于 2013-02-19T21:34:36.213 に答える
0

少しクリーンアップするために、ここに例を示します。

class App:
    _config = None
    _someotherobject = None

def __init__(self, config):
    self._config = config

def main():
  myapp = App(config) # pass a config object to App

if  __name__ =='__main__':main()

別のアプリから、次のことを行う必要があります。

from first_app import App

myapp = App(config)
于 2013-02-19T21:46:08.787 に答える