Secretly passing parameter to function

Modulok modulok at gmail.com
Thu Dec 6 03:30:48 CET 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