How best to pass arbitrary parameters from one function to another

J

John O'Hagan

Hi Pythonistas,

I'm looking for the best way to pass an arbitrary number and type of variables
created by one function to another. They can't be global because they may
have different values each time they are used in the second function.

So far I'm trying to do something like this:


def process_args( [list, of, command-line, arguments] ):

do stuff
return {dictionary : of, local : variables }

def main_function( **kwargs ):

do stuff
return result

kw1 = process_args( [some, list] )
kw2 = process_args( [a, different, list] )

for i in main_function( **kw1 ):

kw2[ var1 ] = i
kw2[ var2 ] = len( i )

for j in main_function(**kw2):

print j

This only seems to work if I specify a default value for every possible
parameter of main_function and also for any others which may be passed to it,
which is a bit tedious because there are very many of them but only a few are
used in any given execution of the program.

Is there a better way to do it? Or have I simply made an error?

Regards and thanks,

John O'Hagan
 
B

Bruno Desthuilliers

John O'Hagan a écrit :
Hi Pythonistas,

I'm looking for the best way to pass an arbitrary number and type of variables
created by one function to another.
>
They can't be global because they may
have different values each time they are used in the second function.

So far I'm trying to do something like this:


def process_args( [list, of, command-line, arguments] ):

do stuff
return {dictionary : of, local : variables }

def main_function( **kwargs ):

do stuff
return result

kw1 = process_args( [some, list] )
kw2 = process_args( [a, different, list] )

for i in main_function( **kw1 ):

kw2[ var1 ] = i
kw2[ var2 ] = len( i )

for j in main_function(**kw2):

print j

This only seems to work if I specify a default value for every possible
parameter of main_function and also for any others which may be passed to it,
which is a bit tedious because there are very many of them but only a few are
used in any given execution of the program.

If this is about commmand line arguments parsing and defaults, you may
want to have a look at the optparse package in the stdlib.

Also, kwargs work fine with default arguments too, ie:


def func(arg1=1, arg2='yadda', arg3=None):
print arg1, arg2, arg3

for kw in ({}, {'arg1':42}, {'arg2':'yop', 'arg3' : range(5)}):
func(**kw)

HTH
 
S

Steven D'Aprano

Hi Pythonistas,

I'm looking for the best way to pass an arbitrary number and type of
variables created by one function to another. They can't be global
because they may have different values each time they are used in the
second function.

So far I'm trying to do something like this:


def process_args( [list, of, command-line, arguments] ):


If you are trying to process commandline args, I suggest you don't re-
invent the wheel. Have a look at the two standard modules, optparse and
getopt. Of the two, getopt is probably simpler to get started with, but
optparse is more powerful.


To answer your more general question, see below.

do stuff
return {dictionary : of, local : variables }

def main_function( **kwargs ):

do stuff
return result

kw1 = process_args( [some, list] )
kw2 = process_args( [a, different, list] )

for i in main_function( **kw1 ):

kw2[ var1 ] = i
kw2[ var2 ] = len( i )

for j in main_function(**kw2):

print j

This only seems to work if I specify a default value for every possible
parameter of main_function and also for any others which may be passed
to it, which is a bit tedious because there are very many of them but
only a few are used in any given execution of the program.

Er, yes. Presumably main_function actually does something. So it expects
some arguments, and if the arguments aren't given, then it will fail. To
prevent it failing when arguments aren't given, they must have default
values. So define them, once, and be done with it:

def main_function(a=1, b=2, c=3, d=4):
dostuff
return result

Now this will work fine:

result = main_function( **{'a': 22, 'd': 33} )

and b and c will take their default values and everything works well.
Default values are a feature, not a problem to be solved.



As for your nested for-loops (see above), I'm guessing that you're trying
to copy items from one dictionary kw1 to another kw2, before processing
kw2. You should check out the update method on dictionaries. Either of:

kw2.update(kw1)
kw1.update(kw2)

will probably do the right thing, depending on which values you want to
take priority in the case of clashes. If you need something even more
flexible, write a small function to merge the two dicts in whatever way
you want. Here's one example:

def merge(kw1, kw2):
"""Merge dict kw1 to kw2 and return a new dict."""
new = kw2.copy()
for key, value in kw1.items():
if key in kw2:
# clash, keep the biggest value
new[key] = max(value, kw2[key])
else:
new[key] = value
return new
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top