Question

Is it possible to pass import a module with some parameter in python ?

All I mean by parameter is that there exists a variable in the module which is not initialized in that module, still I am using that variable in that module. In short, I want behaviour similar to function but unlike function, I want the variables of module to be exposed in the calling code.

eg

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)

I want all random variables in a.py to be exposed to MCMC. I am open to a better approach for my problem at hand, but I would also like to know whteher passing arguments to modules is possible in python or not

Was it helpful?

Solution

As @otus already answered, there is no way to pass parameters to modules.

I think you are following some of the introductory examples for PyMC2, which use a pattern where a module wraps all the code for the nodes in a Bayesian model. This approach is good for getting started, but, as you have found, can be limiting, when you want to run your model with a range of variations.

Fortunately, PyMC2 can create an MCMC object from a list or a dictionary as well as a module. What I recommend in this case is just what @oleg-s suggested in the comments: use a function. You can end the function with return locals() to get a dictionary of everything that would have been in the module, and this is suitable input to the pymc.MCMC constructor. Here is an example:

# 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))

OTHER TIPS

There is no way to pass parameters to modules. However, you could use a global in a third module for this:

# a.py
parameter = None

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

# c.py
import a
# use a.parameter

Of course, this only works if nothing else imports c, because modules only get imported once.

there are various approaches to do so, here is just a silly and simple one:

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...
#

I found it helpful to define global variables, and allow these to be set by an init function.

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']

Then all the user has to do is remember to initialize the module before using these methods:

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

Note, I would NOT use this on a module that I expect to spread publicly. This is more for single-file modules for my own personal use.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top