On Nov 17, 12:52 am, Aaron Brady <[EMAIL PROTECTED]> wrote: > On Nov 16, 8:16 pm, Aaron Brady <[EMAIL PROTECTED]> wrote: > > On Nov 16, 12:52 am, Steven D'Aprano <[EMAIL PROTECTED] > > > I've given practical reasons why the > > > Python choice is better. If you want default argument to be created from > > > scratch when the function is called, you can get it with little > > > inconvenience, but the opposite isn't true. It is very difficult to get > > > static default arguments given a hypothetical Python where default > > > arguments are created from scratch. There's no simple, easy idiom that > > > will work. The best I can come up with is a convention: > > > I'm not so sure. > > > ## Default evaluated at definition time. (Current.) > > > # Static arg. > > def f( a= [] ): > > ... > > > # Non-static arg. > > def f( a= None ): > > if a is None: a= [] > > Oops. Forgot one, after the subsequent posts. > > # Non-static arg. > @nonstatic( a= list ) > def f( a ): > ... > > This can achieve the 'if a is None' effect. 'nonstatic' takes a > callable or a string, '@nonstatic( a= "[]" )'. > > I don't see a way to achieve George Sakkis's example: > > if y is None: y = x*x > if z is None: z = x+y > > Without a change to the language (the other options don't need one). > > #emulates 'def foo(x, y=`x*x`, z=`x+y`):' > @nonstatic( y= 'x*x' ) #illegal > @nonstatic( z= 'x+y' ) #illegal > def foo(x, y, z): > return x+y+z
Sorry for the second reply to myself. With a small change, the above works (excited!), using George Sakkis's 'getcallargs' recipe: 'Recipe 551779: Introspecting call arguments', http://code.activestate.com/recipes/551779/ #emulates 'def foo(x, y=`x*x`, z=`x+y`):' @nonstatic( y= 'x*x', z= 'x+y', a= '[]' ) def foo(x, y, z, a): a.append( 0 ) print x, y, z, a return x+y+z print foo( 2 ) print foo( 1 ) /Output: 2 4 6 [0] 12 1 1 2 [0] 4 So, + a fraction for adding 'nonstatic' to 'functools', because there is such high demand for it. We could just say, 'see the "nonstatic" function!' when newbies ask. + a fraction on string or callable. No change to language, no new syntax. Note: some concern about the **kwargs iteration over variables in the same order they appear in the arguments to the decorator, may be a deal-breaker. In reply to Steve Holden, > Consider, though, the case were one argument value has to refer to > another. I would say the function body is the proper place to be doing > that computation. You appear to feel the def statement is the > appropriate place. If multiple statements are needed to perform the > argument initialization, how would you then propose the problem should > be solved? I don't advocate prohibiting initialization of variables in the function body, just adding this utility decorator. Both places are appropriate to perform the initialization. I don't imagine the decorator can cover every use case, just many. If the **kwargs dictionary can reproduce the order in which the args appeared, just initialize them in that order. Otherwise, since each variable can only have one value in **kwargs, loop over the variables, passing on "NameError: name ... is not defined", until all variables are defined or no assignments can be made. It requires O( n^2 ) running time only on the first time through, since we can cache the order that the assignments succeeded in. -- http://mail.python.org/mailman/listinfo/python-list