Static variables [was Re: syntax difference]
Chris Angelico
chris.angelico at 1
Sat Jun 23 15:16:58 EDT 2018
From: "Chris Angelico" <chris.angelico at 1:261/38.remove-r7u-this>
From: Chris Angelico <rosuav at gmail.com>
On Sat, Jun 23, 2018 at 1:51 PM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> 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!
>
Okay, that makes sense. So in a way, static variables would be like closure
variables with an invisible outer function. These would be roughly equivalent:
def f():
static x = 0
x += 1
return x
def make_f():
x = 0
def f():
nonlocal x
x += 1
return x
return f
f = make_f()
I don't think LOAD_FAST is appropriate (those cells get disposed of when the
function returns), but transforming those lookups into closure lookups would be
a reasonable way to do it I think.
For getting rid of the "len=len" trick, though, I would REALLY like to
transform those into LOAD_CONST. That'd be a fun bytecode hack all on its own.
In fact, I'm gonna have a shot at that. An "early bind these names" decorator.
ChrisA
-+- BBBS/Li6 v4.10 Toy-3
+ Origin: Prism bbs (1:261/38)
--- BBBS/Li6 v4.10 Toy-3
* Origin: Prism bbs (1:261/38)
More information about the Python-list
mailing list