import a module with parameter in python
是否可以在python中传递带有某些参数的导入模块?
我所指的参数是,模块中存在一个未在该模块中初始化的变量,但我仍在该模块中使用该变量。简而言之,我希望行为与函数相似,但与函数不同,我希望在调用代码中公开模块的变量。
如
A.Py
1 2 3 | #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
1 2 | import a #I want some way tr pass value of training_pool m = pymc.MCMC(a) |
我希望a.py中的所有随机变量都暴露在mcmc中。对于手头的问题,我愿意采用更好的方法,但我也想知道为什么在Python中可以将参数传递给模块
正如@otus已经回答的那样,无法将参数传递给模块。
我认为您正在遵循PYMC2的一些介绍性示例,其中使用的模式是模块将节点的所有代码包装在贝叶斯模型中。这种方法对于开始是很好的,但是,正如您已经发现的,当您想要用一系列的变化来运行您的模型时,可能会受到限制。
幸运的是,pymc2可以从列表或字典以及模块中创建一个mcmc对象。在这种情况下,我推荐的只是@oleg-s在注释中建议的:使用函数。您可以使用
1 2 3 4 5 6 7 8 9 10 11 12 | # 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() |
1 2 3 4 5 | # b.py import pymc, a training_pool = [0] m = pymc.MCMC(a.model(training_pool)) |
有各种方法可以做到这一点,这里只是一个愚蠢而简单的方法:
Me.Py
1 2 3 4 5 6 7 8 9 10 11 12 | """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) |
模块化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | """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... # |
无法将参数传递给模块。但是,您可以在第三个模块中为此使用全局:
1 2 | # a.py parameter = None |
1 2 3 4 | # b.py import a a.parameter = 4 import c |
1 2 3 | # c.py import a # use a.parameter |
当然,只有在没有其他东西导入C时,这才有效,因为模块只导入一次。
我发现有助于定义全局变量,并允许这些变量由init函数来设置。
1 2 3 4 5 6 7 8 | 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'] |
然后,所有用户必须记住在使用这些方法之前初始化模块:
1 2 | import module module.init('config.ini') |
注意,我不会在我希望公开传播的模块上使用这个。这更适合我个人使用的单个文件模块。