You can just use nonlocal variables:

def stator():
    static_var_1 = 0

    def myfunc(n):
        nonlocal static_var_1
        static_var_1 += n
        return static_var_1

    return myfunc

myfunc = stator()
del stator

Or you can attach any variable to the function itself:

def myfunc(n):
    if not hasattr(myfunc, "static_var_1"):
        myfunc.static_var_1 = 0
    myfunc.static_var_1 += n
    return myfunc.static_var_1


There are several options to get the effect that static variables would
have,
not to mention that states of this type are better held as class attributes
anyway.

BTW:
# callable singleton - AKA "function":
class myfunc(metaclass=lambda *args: type(*args)()):
    def __init__(self):
        self.static_var_1 = 0

    def __call__(self, n):
        self.static_var_1 += n
        return self.static_var_1


Or, as you put it in the first e-mail, the static var could be built into a
data structure in
the default arguments of the function.

(There are also contextvars, threading.local, etc...)

I can't see a separate "static"  declaration being of any use.
Beginners needing the functionality should just resort to either globals or
plain classes to keep state. As you get the way Python works,
there are plenty of ways to keep the state, without making
the language more complicated.




On Thu, 27 May 2021 at 14:06, Chris Angelico <ros...@gmail.com> wrote:

> On Fri, May 28, 2021 at 2:44 AM Shreyan Avigyan
> <pythonshreya...@gmail.com> wrote:
> >
> > My proposal is somewhat the sum of all of your ideas. Well I propose
> there should a STORE_STATIC_FAST opcode that stores a static variable.
> Static variable will be declared only once and will be initialized to None
> (statement syntax will be similar to that of global). It will be
> initialized in MAKE_FUNCTION. Now it will be set by STORE_STATIC_FAST.
> Where will the variables be stored? It will have references in locals and
> __statics__. Therefore LOAD_FAST can find it. So I don't hope there will be
> performance decrease but performance increase is also not guaranteed. :-)
> >
>
> The duplicated store fixes half the problem, but it still fails on the
> recursion example that I posted in reply to Steve. It would be a nice
> optimization, but it may or may not be sufficient.
>
> > And if these are thread unsafe then is __defaults__ also thread unsafe?
> >
>
> Thread safety isn't a problem with constants. Python guarantees that
> internal details (like CPython's reference counts) aren't going to be
> trampled on, and inside your code, nothing is going to change
> __defaults__ (unless you're doing something bizarre, in which case it
> isn't about __defaults__ any more). Thread safety only becomes an
> issue when you have something like this:
>
> counter = 0
> def get_next():
>     global counter
>     counter += 1
>     return counter
>
> This disassembles to:
>
>   6           0 LOAD_GLOBAL              0 (counter)
>               2 LOAD_CONST               1 (1)
>               4 INPLACE_ADD
>               6 STORE_GLOBAL             0 (counter)
>
>   7           8 LOAD_GLOBAL              0 (counter)
>              10 RETURN_VALUE
>
> A context switch can happen between any two of those instructions.
> That means one thread could load the global, then another thread could
> load the same value, resulting in both of them writing back the same
> incremented value. Or, between opcodes 6 and 8 (between the lines of
> Python code), you could store the value, then fetch back a different
> value.
>
> None of this is a problem if you're using constants. The only reason
> to use statics instead of global constants is performance - the
> "len=len" trick is specific to this performance advantage - but you
> don't have to worry about thread safety.
>
> ChrisA
> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/DD62RX2ZFOOKQFIHXRFH2LABOFYE4HSZ/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/3BWG6CPWAVS4POG6WICZOHPVHNWWJTUT/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to