web-dev-qa-db-ja.com

python

pythonにいくつかのパラメータを持つモジュールのインポートを渡すことは可能ですか?

parameterとは、モジュール内に初期化されていない変数が存在するということですが、それでもそのモジュールでその変数を使用しています。つまり、関数と同様の動作が必要ですが、関数とは異なり、モジュールの変数を呼び出し元のコードで公開する必要があります。

例えば

a.py

#lists like data, count, prob_distribution are constructed from training_pool (not initialized in this file)
x = pymc.Uniform('x', lower = 0, upper = 1)
rv = [ Multinomial("rv"+str(i), count[i], prob_distribution[i], value = data[i], observed=True) for i in xrange(0, len(count)) ]

b.py

import a  #I want some way tr pass value of training_pool
m = pymc.MCMC(a)

A.pyのすべての確率変数をMCMCに公開したいと思います。私は目前の問題に対してより良いアプローチを受け入れていますが、モジュールに引数を渡すことがpythonかどうか)で可能かどうかも知りたいです

12
turing

@otusがすでに回答しているように、パラメータをモジュールに渡す方法はありません。

モジュールがベイズモデルのノードのすべてのコードをラップするパターンを使用する、PyMC2のいくつかの紹介例に従っていると思います。このアプローチは開始には適していますが、さまざまなバリエーションを使用してモデルを実行する場合は、制限される可能性があります。

幸い、PyMC2は、モジュールだけでなく、リストまたは辞書からMCMCオブジェクトを作成できます。この場合に私がお勧めするのは、@ oleg-sがコメントで提案したものです。関数を使用してください。関数をreturn locals()で終了して、モジュールに含まれるすべての辞書を取得できます。これは、pymc.MCMCコンストラクターへの適切な入力です。次に例を示します。

# a.py
from pymc import *

count = [10, 10] # perhaps good to put this stuff in data.py
prob_distribution = [[.5, .5], [.1, .2, .7]]
data = [[2, 8], [2, 3, 5]]

def model(training_pool):
    x = Uniform('x', lower = 0, upper = 1)
    rv = [ Multinomial("rv"+str(i), count[i], prob_distribution[i], value = data[i], observed=True) for i in training_pool ]

    return locals()

# b.py
import pymc, a

training_pool = [0]
m = pymc.MCMC(a.model(training_pool))
6

これを行うにはさまざまなアプローチがありますが、これはばかげた単純なアプローチです。

main.py

"""A silly example - main supplies a parameter
"""

import sys,os

print os.path.basename(__file__)+":Push it by: --myModuleParam "+str(123)
sys.argv.append('--myModuleParam')
sys.argv.append(123)
import module


print os.path.basename(__file__)+":Pushed my  param:"+str(module.displayMyParam)

module.py

"""A silly example - module consumes parameter
"""

import sys,os

displayMyParam = 'NotYetInitialized'

for px in sys.argv:
    if px == '--myModuleParam':
        idx = sys.argv.index(px)
        sys.argv.pop(idx) # remove option
        displayMyParam = sys.argv[idx]
        sys.argv.pop(idx) # remove value
        print os.path.basename(__file__)+":Got my param:"+str(displayMyParam)

#
# That's it...
#
2
acue

モジュールにパラメータを渡す方法はありません。ただし、これには3番目のモジュールでグローバルを使用できます。

# a.py
parameter = None

# b.py
import a
a.parameter = 4
import c

# c.py
import a
# use a.parameter

もちろん、モジュールは一度しかインポートされないため、これは他にcをインポートしない場合にのみ機能します。

2
otus

グローバル変数を定義し、それらをinit関数で設定できるようにすると便利だと思いました。

def init(config_filename=CONFIG_FILENAME):
    config = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation())
    config.read(config_filename)

    global YEARS
    YEARS = config['DEFAULT']['YEARS']
    global FEATURES
    FEATURES = config['DEFAULT']['FEATURES']

次に、ユーザーがしなければならないのは、これらのメソッドを使用する前にモジュールを初期化することを忘れないでください。

import module
module.init('config.ini')

公に広めることが期待されるモジュールではこれを使用しないことに注意してください。これは、私自身が個人的に使用する単一ファイルモジュール用です。