1

我使用一个数组来存储需要连续调用的函数:

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'),
]

我现在想做的是TRANSFORM_PIPELINE用给定的参数和一个动态的参数来调用。

我脑子里有这样的东西,应该循环调用do_xslt('passX.xsl', xml)

for transform in TRANSFORM_PIPELINE:
    xml = transform(xml) 

这种做法当然是错误的。但是如何在 Python 中使用正确的方法呢?

4

2 回答 2

2

用于functools.partial()部分应用函数:

from functools import partial
TRANSFORM_PIPELINE = [
    partial(do_xslt, 'pass1.xsl'),
    partial(do_xslt, 'pass2.xsl'),
    partial(do_xslt, 'pass3.xsl')
]

调用返回的函数partial()将调用do_xslt('pass1.xsl', *args, **kwargs)并作为传递给新函数的参数*args**kwargs

演示:

>>> 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
于 2012-05-11T08:06:26.103 回答
2

使用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'),
]

或者,您也可以像这样使用闭包:

def do_xslt(xsl):
    def inner(xml):
        newxml = dosomethingwithit(xsl,xml)
        return newxml
    return inner

这样,您可以完全按照现在的方式保留 TRANSFORM_PIPELINE。

于 2012-05-11T08:06:58.930 回答