I find myself in a need of working with functions and objects who take a large number of variables.
For a specific case, consider a function from a separated module which takes N different variables, which are then pass them on to newly instanced object:
def Function(Variables):
Do something with some of the variables
object1 = someobject(some of the variables)
object2 = anotherobject(some of the variables, not necessarily as in object1)
While i can just pass a long list of variables, from time to time i find myself making changes to one function, which requires making changes in other functions it might call, or objects it might create. Sometimes the list of variables might change a little.
Is there a nice elegant way to pass a large group of variables and maintain flexibility?
I tried using kwargs in the following way:
def Function(**kwargs):
Rest of the function
and calling Function(**somedict), where somedict is a dictionary has keys and values of all the variables i need to pass to Function (and maybe some more). But i get an error about undefined global variables.
Edit1:
I will post the piece of code later since i am not at home or the lab now. Till then i will try to better explain the situation.
I have a molecular dynamics simulation, which take few dozens of parameters. Few of the parameters (like the temperature for example) need to be iterated over. To make good use of the quad core processor i ran different iterations in parallel. So the code starts with a loop over the different iteration, and at each pass send that parameters of that iteration to a pool of workers (using the multiprocessing module). It goes something like:
P = mp.pool(number of workers) # If i remember correctly this line
for iteration in Iterations:
assign values to parameters
P.apply_async(run,(list of parameters),callback = some post processing)
P.close()
P.join()
The function run takes the list of parameters and generates the simulation objects, each take some of the parameters as their attributes.
Edit2:
Here is a version of the problematic function. **kwargs
contain all the parameters needed by the 'sim','lattice' and 'adatom'.
def run(**kwargs):
"""'run' runs a single simulation process.
j is the index number of the simulation run.
The code generates an independent random seed for the initial conditios."""
scipy.random.seed()
sim = MDF.Simulation(tstep, temp, time, writeout, boundaryxy, boundaryz, relax, insert, lat,savetemp)
lattice = MDF.Lattice(tstep, temp, time, writeout, boundaryxy, boundaryz, relax, insert, lat, kb, ks, kbs, a, p, q, massL, randinit, initvel, parangle,scaletemp,savetemp,freeze)
adatom = MDF.Adatom(tstep, temp, time, writeout, boundaryxy, boundaryz, relax, insert, lat, ra, massa, amorse, bmorse, r0, z0, name, lattice, samplerate,savetemp,adatomrelax)
bad = 1
print 'Starting simulation run number %g\nrun' % (j+1)
while bad is 1:
# If the simulation did not complete successfuly, run it again.
bad = sim.timeloop(lattice,adatom1,j)
print 'Starting post processing'
# Return the temperature and adatomś trajectory and velocity
List = [j,lattice.temp , adatom1.traj ,adatom1.velocity, lattice.Toptemp, lattice.Bottomtemp, lattice.middletemp, lattice.latticetop]
return List