On Thu, May 27, 2021 at 8:19 AM Steven D'Aprano <[email protected]> wrote:

> On Thu, May 27, 2021 at 07:56:16AM -0000, Shreyan Avigyan wrote:
>
> > This idea proposes to add a keyword
> > (static, maybe?) that can create static variables that can persist
> > throughout the program yet only accessible through the function they
> > are declared and initialized in.
>
>
> Here is a sketch of how this could work, given a function like this:
>
>     def func(arg):
>         static spam, eggs
>         static cheese = expression
>         ...
>
>
> At function declaration time, the two static statements tell the
> compiler to:
>
> * treat spam, eggs and cheese as local variables (use LOAD_FAST instead
>   of LOAD_GLOBAL for lookups);
>
> * allocate static storage for them using the same (or similar) mechanism
>   used for function default values;
>
> * spam and eggs get initialised as None;
>
> * cheese gets initialised to the value of `expression`, evaluated
>   at function declaration time just as default arguments are.
>
>
> When the function is called:
>
> * the interpreter automatically initialises the static variables
>   with the stored values;
>
> * when the function exits (whether by return or by raising an
>   exception) the static storage will be updated with the current
>   values of the variables.
>
> As a sketch of one possible implementation, the body of the function
> represented by ellipsis `...` might be transformed to this:
>
>     # initialise statics
>     spam = LOAD_STATIC(0)
>     eggs = LOAD_STATIC(1)
>     cheese = LOAD_STATIC(2)
>     try:
>         # body of the function
>         ...
>     finally:
>        STORE_STATIC(spam, 0)
>        STORE_STATIC(eggs, 1)
>        STORE_STATIC(cheese, 2)
>
>
>
Couldn't you already get pretty close to this by attaching your static
values to the function __dict__?

Example:

def func():
    print(func.a)
func.a = 1

Usage:

 >>> func()
 1

Of course that is slower because there is an attribute lookup.

But could there be a decorator that links the function __dict__ to
locals(), so they are intertwined?

@staticify({ 'a':1})
def func():
    print(a)
    print(b)
func.b = 2

Usage:

 >>> func()
 1
 2
 >>> func.a = 3  # dynamic update of func.__dict__
 >>> func()
 3
 2

The locals dict in the function body would look something like this:

ChainMap(locals(), {'a':1})

---
Ricky.

"I've never met a Kentucky man who wasn't either thinking about going home
or actually going home." - Happy Chandler


> One subtlety: what if the body of the function executes `del spam`? No
> problem: the spam variable will become undefined on the next function
> call, which means that subsequent attempts to get its value will raise
> UnboundLocalError:
>
>
>     try:
>         x = spam + 1
>     except UnboundLocalError:
>         spam = 0
>         x = 1
>
>
> I would use this static feature if it existed. +1
>
>
>
> --
> Steve
>

 Same thing would happen with my idea: del a would delete a from the
func.__dict__ (just like with ChainMap). But if you add it back again
later, it would not be static anymore.

Example:

@staticify('a': 1)
def func():
    print(a)  # fast static lookup
    del a  # static is deleted
    a = 2  # this is local now
    func.b = 3  # but this is a static
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/SB4PZLYCTKRWHNXWVFWIXQC3NEZQRKQL/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to