Secretly passing parameter to function
Modulok
modulok at gmail.com
Wed Dec 5 21:30:48 EST 2012
> Hi all !
>
> I have a problem that is not easy to explained, so I have tried to
> reduce it a lot.
>
> We are using a framework, that we can not modify.
>
> in framework.py:
> def do(something):
> '''
> Here we are in a framework that can not be modified ...
> It does a lot of things
>
> and finally:
> '''
> something()
>
> in test.py:
> from framework import *
>
> def step1():
> print "Do step1"
>
> def step2():
> print "Do step2"
>
>
> # We ask the framework to do some work.
> do(step1)
> do(step2)
> do(step3)
>
>
> We are writing step1, step2, ... and asking the framework to process them.
> Everything is ok, until we want to add a parameter to some steps.
> We want to be able to do that:
>
> in test.py:
> from framework import *
>
> def step1(param):
> print "Do step1 with param"
>
> def step2():
> print "Do step2"
>
>
> # We ask the framework to do some work.
>
> do(step1, param = None)
> do(step1, param = [0, 1, 5]) # again
> do(step2)
>
> Of course it does not work ...
> TypeError: do() takes exactly 1 argument (2 given)
>
> And we can not modify the framework (in which "do" is defined.
>
> One solution would be to use a global variable that can be set before
> each step. But it is not very elegant ...
>
> One other approach would be to add dynamically an attribute the the
> step1 function, and retrieve it inside the function, but it is perhaps
> overkill.
>
> Do you have some ideas ?
Olivier,
I would create a partial object using the functools module, but I would also
wrap it in a decorator so I could call my functions as usual. Here's an
example:
# File: framework.py:
def do(something):
print("Framework in action...")
return something()
# File: test.py:
import functools
import framework
def pack(func):
"""Return a function object to be called later."""
def f(*args, **kwargs):
"""Call the framework passing a partial object to be called."""
print("Wrapper in action...")
part = functools.partial(func, *args, **kwargs)
return framework.do(part) #<-- Call the simplified function.
return f #<-- Return the function object to-be-called.
# Usage: Just wrap your defs with the decorator '@pack':
@pack
def step1(x, y):
print(x, y)
@pack
def step2(a):
return sum(a)
@pack
def step3():
print("Amazing!")
# Call your functions as usual e.g: step1(3, 5)...
In theory everything should just work. I tested the above example and it seemed
to work just fine with my limited testing.
Good luck!
-Modulok-
More information about the Python-list
mailing list