How do I dynamically create functions without lambda?

Steven D'Aprano steve at REMOVETHIScyber.com.au
Fri Jan 27 19:35:07 EST 2006


On Fri, 27 Jan 2006 11:41:56 -0800, Kay Schluehr wrote:

> 
> Russell wrote:
>> I want my code to be Python 3000 compliant, and hear
>> that lambda is being eliminated. The problem is that I
>> want to partially bind an existing function with a value
>> "foo" that isn't known until run-time:
>>
>>    someobject.newfunc = lambda x: f(foo, x)
>>
>> The reason a nested function doesn't work for this is
>> that it is, well, dynamic. I don't know how many times
>> or with what foo's this will be done.
>>
>> Now, I am sure there are a half-dozen ways to do this.
>> I just want the one, new and shiny, Pythonic way. ;-)
> 
> If you want to code partial application without lambda I recommend
> using the code presented in the accepted PEP 309 that will be
> implemented in the functional module in Python 2.5.
> 
> http://www.python.org/peps/pep-0309.html


Fascinating. A couple of thoughts:

- I really wish that people would make up their minds about what currying
is, and how it differs from partials and closures. If the people who
do know can't agree, how do they expect the rest of us to understand?

- What, if anything, is the difference between a closure and an iterator?
Is an iterator just a closure wrapped up with an API?

- The first sample code seems needlessly confusing to me. It gives:

class partial(object):
    def __init__(*args, **kw):
        self = args[0]
        self.fn, self.args, self.kw = (args[1], args[2:], kw)
    def __call__(self, *args, **kw):
        if kw and self.kw:
            d = self.kw.copy()
            d.update(kw)
        else:
            d = kw or self.kw
        return self.fn(*(self.args + args), **d)

It seems to me to needlessly break the convention that the first argument
is self, to no benefit and considerable reduction in clarity. After some
experimentation, I worked out what it was doing, and realised that it
would work just as well but much less obscurely if the __init__ function
was written as:

    def __init__(self, fn, *args, **kw):
        self.fn, self.args, self.kw = fn, args, kw


- It seems a shame to me that having created a partial _function_ using
that technique, type(partial(...)) returns <class partial>. It would be
nicer if the type made it more obvious that the instance was callable.
Something like <callable class partial> perhaps? Is there any way for a
class to customise the type representation?



-- 
Steven.




More information about the Python-list mailing list