2

同僚は、独自のファイルで定義されたハードコーディングされた構成を使用するライブラリを持っています。例えば:

定数.py:

API_URL="http://example.com/bogus"

ライブラリの残りの部分では、次の方法で構成にアクセスします。

from constants import API_URL

ご想像のとおり、これはあまり柔軟ではなく、テスト中に問題が発生します。構成を変更したい場合は、ソース コード管理にある constants.py を変更する必要があります。

当然のことながら、JSON または YAML ファイルから構成をロードしたいと思います。問題なく構成をオブジェクトに読み込むことができます。constants.pyコードを壊さずにモジュールをオーバーライドして、たとえば、各グローバルAPI_URLがファイルによって提供される値に置き換えられるようにする方法はありますか?

私は、それぞれの後from constants import ...に次のようなものを追加できると考えていました:

from constants import *  # existing configuration import
import json
new_config = json.load(open('config.json'))  # load my config file into a dictionary
constants.__dict__.update(new_config)        # override any constants with what I've loaded

もちろん、これの問題は、あまり「DRY」ではなく、もろいように見えることです.

これをもっときれいにするための提案はありますか?ありがとう!

編集:とにかく私のアプローチがうまくいかないようです。「from import *」は、モジュールの値を現在のモジュールのグローバルスコープにコピーすると思いますか?

ダブル編集: いいえ、機能します。私はただ混乱しています。しかし、これを X 個の異なるファイルで行うのではなく、可能であれば透過的に動作させたいと考えています。

4

1 に答える 1

1

from module import <name>インポート モジュールのグローバル名前空間に、インポートされたオブジェクトへの参照を作成します。それが不変である場合、それは、それをインポートしたモジュールの値にモンキーパッチを適用する必要があることを意味します。

あなたの唯一の望みは、定数を最初にインポートし、そのモジュールの名前にモンキーパッチを当てることです。その後のインポートでは、monkeypatched 値が使用されます。

元のモジュールに早期にパッチを適用するには、次の手順で十分です。

import constants

for name, value in new_config.iteritems():
    setattr(constants, name, value)
于 2013-09-13T17:44:26.047 に答える