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
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to