2

モジュール内でロード時に init() 関数を呼び出す中央モジュールがあります。

import x
import y
import z

def init():
    ....

init()

if __name__ == '__main__':
    ...

これは、次のようなステートメントですべてのアプリケーション モジュールに取り込まれます。

if __name__ == '__main__':
    import central_module as b
    b.do_this()
    b.do_that()

init() は多くの悪いことを行いますが、特にデータベースへの接続を確立します。このため、単体テストが中断され、私が作成したモジュールは、モジュールをインポートして初期化を明示的に呼び出す通常の動作を想定しています。

一番上にINITIALIZE変数を追加することで回避策を実装しました:

#INITIALIZE = True
INITIALIZE = False  # for DEV/test

if INITIALIZE:
    init()

ただし、テストを実行したり開発を行ったりするためにそのファイルを編集し、コミットしてプッシュする準備ができたら変更を元に戻す必要があります。

政治的な理由から、私はそれを修正するだけでは何の牽引力も得ていません:

import central_module as b
...
    b.init()
    b.do_this()
    b.do_that()

モジュールのロード時にその呼び出しをより透過的に無効にする方法はありますか? 問題は、モジュールがインポートされるまでに、すでにデータベースへの接続が試行されている (そして失敗している) ことです。

今のところ私の最善のアイデアは、INITIALIZE変数を以前のインポートに移動し、テストでそれをインポートし、初期化をFALSEに設定してからcentral_moduleをインポートすることです.

私は政治的な側面 (arg) に取り組み続けますが、既存のすべてのスクリプトを中断することなくその init 呼び出しを無効にするためのより良い回避策があるかどうか疑問に思っていました。

4

4 に答える 4

3

これが私の考えですが、悪いかもしれません:

  1. モジュールをファイルとして開き、ソースを読み込みます。
  2. ast.parse()AST に解析するために使用します。
  3. 問題のある関数呼び出しが見つかるまで AST をたどり、それを削除します。
  4. 変更された AST を評価し、 によって作成された新しいモジュールに挿入し、 に詰め込みimp.new_module()ますsys.modules
  5. お尻に噛み付いた場合に適切な初期化がわからないという事実を除いて、まったく必要ないというコミット メッセージでクレイジーなハックをコミットします。
于 2013-06-05T00:48:33.287 に答える
3

ハックの簡単な変更INITIALIZEは、環境変数から取得することです。そうすれば、それらのテストを実行するためにコードを変更する必要がなくなり、悪い init を実際に修正できるようになるまで、ハッキングを減らすことができます。

 INITIALIZE = os.environ.get('DO_TERRIBLE_INITIALIZE', False)
 if INITIALIZE:
     ....

そして、値はそのセットである限り、何でもかまいません。

 export DO_TERRIBLE_INITIALIZE=ohgodwhy
于 2013-06-05T00:56:10.057 に答える
1

テスト環境と本番環境で異なる動作が必要な場合は、環境変数を使用するのが標準です。

import os

if os.getenv("MYAPPENV") != "test":
    init()

次に、開発時に MYAPPENV を「テスト」に設定するだけでよく、init() はロード時に実行されません。その変数が環境で設定されていない場合、または「test」以外の値を持っている場合は、デフォルトの動作が得られます。また、モジュールのソース ファイルを常に再編集する必要はありません。

于 2013-06-05T00:54:42.457 に答える
0

この問題はテストに固有のものであるため、私が見ているように、init を呼び出す必要がありますが、それに対して行われた悪いこと (外部プロシージャ) は偽のコードに置き換えられています。init の呼び出しを避けるべきではないと思います。

于 2013-06-05T01:03:23.797 に答える