Reputation: 3742
I use an array for storage of functions which needs to be called in a row:
def do_xslt(xsl, xml):
newxml = dosomethingwithit(xsl,xml)
return newxml
TRANSFORM_PIPELINE = [
do_xslt('pass1.xsl'),
do_xslt('pass2.xsl'),
do_xslt('pass3.xsl'),
]
what I now want to do is to call the TRANSFORM_PIPELINE
with its given argument and a dynamic one.
I have something like this in my mind which should call in a loop do_xslt('passX.xsl', xml)
for transform in TRANSFORM_PIPELINE:
xml = transform(xml)
This approach is of course wrong. But how to make the right way in Python?
Upvotes: 1
Views: 98
Reputation: 318488
Use functools.partial()
to partially apply the function:
from functools import partial
TRANSFORM_PIPELINE = [
partial(do_xslt, 'pass1.xsl'),
partial(do_xslt, 'pass2.xsl'),
partial(do_xslt, 'pass3.xsl')
]
Calling the functions returned by partial()
will call do_xslt('pass1.xsl', *args, **kwargs)
with *args
and **kwargs
being the arguments passed to the new function.
Demo:
>>> def do_xslt(xsl, xml):
... print 'do_xslt(%r, %r)' % (xsl, xml)
... return xml + '*' + xsl
...
>>> from functools import partial
>>> TRANSFORM_PIPELINE = [
... partial(do_xslt, 'pass1.xsl'),
... partial(do_xslt, 'pass2.xsl'),
... partial(do_xslt, 'pass3.xsl')
... ]
>>> x = 'xml is lame'
>>> for transform in TRANSFORM_PIPELINE:
... x = transform(x)
... print x
...
do_xslt('pass1.xsl', 'xml is lame')
xml is lame*pass1.xsl
do_xslt('pass2.xsl', 'xml is lame*pass1.xsl')
xml is lame*pass1.xsl*pass2.xsl
do_xslt('pass3.xsl', 'xml is lame*pass1.xsl*pass2.xsl')
xml is lame*pass1.xsl*pass2.xsl*pass3.xsl
Upvotes: 2
Reputation: 3661
Use functools.partial()
- http://docs.python.org/library/functools.html#functools.partial
TRANSFORM_PIPELINE = [
functools.partial(do_xslt, 'pass1.xsl'),
functools.partial(do_xslt, 'pass2.xsl'),
functools.partial(do_xslt, 'pass3.xsl'),
]
Alternatively, you can also use a closure like so:
def do_xslt(xsl):
def inner(xml):
newxml = dosomethingwithit(xsl,xml)
return newxml
return inner
This way, you can keep the TRANSFORM_PIPELINE exactly the way you have it now.
Upvotes: 2