> But this all reminds me of the discussion > over itemgetter/attrgetter. They also special-case particular uses of > lambda, and in those cases the stated benefits were speed and > (arguably) readability (I still dislike the names, personally).
I wouldn't use those as justification for partial(). The names suck and the speed-up is small. They were directed at a specific and recurring use case related to key= arguments. > I think partial hits a similar spot - it covers a fair number of > common cases, Are you sure about that? Contriving examples is easy, but download a few modules, scan them for use cases, and you may find, as I did, that partial() rarely applies. The argument order tends to be problematic. Grepping through the standard library yields no favorable examples. In inspect.py, you could replace "formatvarkw=lambda name: '**' + name" with "partial(operator.add, '**') but that would not be an improvement. Looking through the builtin functions also provides a clue: cmp(x,y) # partial(cmp, refobject) may be useful. coerce(x,y) # not suitable for partial(). divmod(x,y) # we would want a right curry. filter(p,s) # partial(filter, p) might be useful. getattr(o,n,d) # we would want a right curry. hasattr(o,n) # we would want a right curry. int(x,b) # we would want a right curry. isinstance(o,c) # we would want a right curry. issubclass(a,b) # we would want a right curry. iter(o,s) # we would want a right curry. long(x,b) # we would want a right curry. map(f,s) # partial(map, f) may be useful. pow(x,y,z) # more likely to want to freeze y or z. range([a],b,[c])# not a good candidate. reduce(f,s,[i]) # could work for operator.add and .mul round(x, n) # we would want a right curry. setattr(o,n,v) # more likely to want to freeze n. > the C implementation is quoted as providing a speed > advantage over lambda. Your recent timings and my old timings show otherwise. > Seriously, not needing to explicitly handle *args and **kw > is a genuine readability benefit of partial. I hope that is not the only real use case. How often do you need to curry a function with lots of positional and keyword arguments? Even when it does arise, it may a code smell indicating that subclassing ought to be used. > Now I wonder. Are my tests invalid, did lambda get faster, or is the > "lambda is slow" argument a myth? The test results are similar to what I got when I had tested the version proposed for Py2.4. The lambda version will win by an even greater margin if you put it on an equal footing by factoring out the attribute lookup with something like f=t.f. Calling Python functions (whether defined with lambda or def) is slower than C function calls because of the time to setup the stack-frame. While partial() saves that cost, it has to spend some time building the new argument tuple and forwarding the call. You're timings show that to be a net loss. Sidenote: Some C methods with exactly zero or one argument have optimized paths that save time spent constructing, passing, and unpacking an argument tuple. Since partial() is aimed at multi-arg functions, that part of "lambda is slower" is not relevant to the comparison. > Hmm, I'm starting to go round in circles here. I also wish that partial() ran faster than closures, that it didn't have limitations, and that it applied in more situations. C'est le vie. Raymond _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com