To: Steven D'Aprano From: Bart <b...@freeuk.com> On 23/06/2018 04:51, Steven D'Aprano wrote: > On Wed, 20 Jun 2018 14:18:19 +1000, Chris Angelico wrote: > >> Ah. Yeah, that would be a plausible feature to add to Python. But in C, >> a static variable is basically the same thing as a global variable, >> except that its name is scoped to the function. There is only one of it. >> What happens in Python? For instance: >> >> def f(): >> def g(): >> static x = 0 >> x += 1 >> return x >> return g >> >> Does the static variable exist once for each instance of g()? If so, >> it'll behave like a closure variable; if not, it'll behave like a >> global. Either way, I'm pretty much certain that people will expect the >> other. > > Yes, but given the normal execution model of Python, only one solution is > valid. Since the function g is created fresh each time f is called, each > one gets a fresh static x. > > If you want all the g's to share the same x, you would write: > > def f(): > static x = 0 > def g(): > x += 1 > return x > return g > > > In this case, every invocation of f shares the same static x, and all the > g's refer to that same x, using the ordinary closure mechanism. In the > earlier case, each invocation of f creates a brand new g with its own x. > > Simple and elegant. > > This could at last get rid of that useful but ugly idiom: > > def function(real, arguments, len=len, int=int, str=str): > ... > > if we allowed the "static" declaration to access the values from the > surrounding scope: > > def function(real, arguments): > static len=len, int=int, str=str > > But I think nicer than that would be a decorator: > > @static(len=len, int=int, str=str) > def function(real, arguments): > ... > > which adds local variables len, int, str to the function, with the given > values, and transforms all the bytecode LOAD_NAME len to LOAD_FAST len > (or whatever). > > (We might need a new bytecode to SET_STATIC.) > > That would be a nice bytecode hack to prove the usefulness of the concept!
This is an example of a simple concept getting so out of hand that it will either never be implemented, or the resulting implementation becomes impractical to use. This is what we're trying to do: def nextx(): static x = 0 x += 1 return x And this is the simplest equivalent code in current Python that will cater for 99% of uses: _nextx_x = 0 def nextx(): global _nextx_x _nextx_x += 1 return _nextx_x No nested functions. No generating new instances of functions complete with a new set of statics each time you happen to refer to the name. (Which sounds to me as useful as creating a new instance of an import when you copy its name, complete with a separate set of its globals. Isn't this stuff what classes are for?) (At what point would that happen anyway; if you do this: g = nextx # hypothetical version would static it will create a new instance of 'nextx'. But it won't create one here, just before () is applied: nextx() # ? Or how about here: listoffunctions = (nextx1, nextx2, nextx3) listoffunctions[i]() # ? ) -- bartc --- BBBS/Li6 v4.10 Toy-3 * Origin: Prism bbs (1:261/38) -- https://mail.python.org/mailman/listinfo/python-list