Oleg Broytmann a écrit :
On Tue, May 19, 2009 at 10:31:00PM +0200, Pascal Chambon wrote:
I could content myself of the proposed solution :
def func (a, b = lambda : []):
But I just dislike the fact that the "dynamic" applies to all the  
defaults, even those which weren't supposed to be dynamic (and writing  
"lambda : lambda : []") doesn't look good).
Would there be any way of separating "to-be-called" lambdas from normal  
ones ? Except with a syntax like "b = dyn(lambda: [])" ?

def func (a, b = lambda : []):

*shame on me - /me must be tired this evening*

Well, with that solution we don't avoid some amount of boiler plate code, but imo the pros are
- we don't have to care about copy/deepcopy constraints, or giving the default argument expression as a string (with all the problems eval() might raise)
- most important for me : we have a pattern that could be broadcasted as a "standard practice", and thus warn newbies about the normal behaviour of default arguments.
If the "dynamic" (or any other proper name) decorator became part of the builtin ones, like staticmethod or classmethod, in my opinion newbies would quickly run into it, get used to it, and we'd have a common practice instead of the numerous ones currently possible to handle dynamic defaults (sentinels, other decorators...).

What do you think ? Is that worth the change compared to the sentinel stuff ?
In my opinion, it's clearly more explicit, and the newbie will never think "that programmer is dumb, he has put None as a default whereas we can directly put lists or any other expressions in the signature, we're not restricted to constants like in other languages" as it might currently be the case.

I'm eventually +1 on such a decorator/lambda mix (in the absence of more straightforward but language-changing syntax)