I have two Python functions, both of which take variable argum开发者_如何学运维ents in their function definitions. To give a simple example:
def func1(*args):
for arg in args:
print arg
def func2(*args):
return [2 * arg for arg in args]
I'd like to compose them -- as in func1(func2(3, 4, 5))
-- but I don't want args
in func1
to be ([6, 7, 8],)
, I want it to be (6, 7, 8)
, as if it was called as func1(6, 7, 8)
rather than func1([6, 7, 8])
.
Normally, I would just use func1(*func2(3, 4, 5))
or have func1
check to see if args[0]
was a list. Unfortunately, I can't use the first solution in this particular instance and to apply the second would require doing such a check in many places (there are a lot of functions in the role of func1
).
Does anybody have an idea how to do this? I imagine some sort of introspection could be used, but I could be wrong.
You can consider writing function decorator that checks if the first argument is a list. Applying decorator to existing functions is a bit simpler than modifying functions.
You can use a Decorator as posted by Yaroslav.
Minimal example:
def unpack_args(func):
def deco_func(*args):
if isinstance(args, tuple):
args = args[0]
return func(*args)
return deco_func
def func1(*args):
return args
def func2(*args):
return args
@unpack_args
def func3(*args):
return args
print func1(1,2,3) # > (1,2,3)
print func2(1,2,3) # > (1,2,3)
print func1(*func2(1,2,3)) # > (1,2,3)
print func1(func2(1,2,3)) # > ( (1,2,3), )
print func3(func2(1,2,3)) # > (1,2,3)
Normally, I would just use
func1(*func2(3, 4, 5))
or have func1 check to see ifargs[0]
was alist
. Unfortunately, I can't use the first solution in this particular instance and to apply the second would require doing such a check in many places (there are a lot of functions in the role offunc1
).
Why can't you use the first solution?
>>> def func1(*args):
for arg in args:
print arg
>>> def func2(*args):
return [2 * arg for arg in args]
>>> func2(3, 4, 5)
[6, 8, 10]
>>> func1(1,2,3)
1
2
3
>>> func1(*func2(3, 4, 5))
6
8
10
>>>
If that wasn't possible, you could still have used func1(*tuple(func2(3, 4, 5)))
(but you don't need to).
精彩评论