Skip to content

Instantly share code, notes, and snippets.

@zinthose
Created September 20, 2023 03:51
Show Gist options
  • Save zinthose/90184a7dcd1c7f9e72f615bd7f5e7ea8 to your computer and use it in GitHub Desktop.
Save zinthose/90184a7dcd1c7f9e72f615bd7f5e7ea8 to your computer and use it in GitHub Desktop.
An over engineered static variable solution. This method allows you to define static variables in a function. This is useful for when you want to save a value for later use in the same function. Treat this as a proof of concept and not a serious solution. It's much easier to just attach a value too the function object. This is just a fun way to …
import inspect
import re
def static(variable_or_default: any) -> any:
"""
An over engineered static variable solution
This method allows you to define static variables in a function. This is
useful for when you want to save a value for later use in the same function.
Treat this as a proof of concept and not a serious solution. It's much
easier to just attach a value too the function object. This is just a fun
way to do it.
This MUST be used within a method / function. It will not work in the global
scope.
This method has very special syntax requirements. It must be called in the
following way:
```python
# Set/Define a static variable
variable = static(default_value)
# Save the value for later use
static(variable)
```
Args:
variable_or_default (any): If method is assigned to a variable, this
will be the default value. If method is called without assignment,
this will be the variable to save.
"""
# Get calling frame
frame = inspect.currentframe()
frame = inspect.getouterframes(frame)[1]
# Get calling function
if hasattr(locals(), frame.function):
func = locals()[frame.function]
else:
func = globals()[frame.function]
# Create static dictionary if it doesn't exist
if not hasattr(func, '_static'):
func._static = {}
# Get the line of code that called this function
string = inspect.getframeinfo(frame[0]).code_context[0].strip()
# Regex pattern to match static variable method call
pattern = r'([A-Za-z+][A-Za-z0-9_]*)?\s*=?\s*static\s*\((.*)\)\s*(?:$|#)'
match = re.search(pattern, string)
# If no match, raise SyntaxError
if match is None:
raise SyntaxError('Invalid syntax for static variable method call')
# Get the variable name and the argument supplied
assignment,argument = match.groups()
# If no assignment, set the variable name to the argument supplied
if assignment is None:
func._static[argument] = variable_or_default
return
# If assignment, not in static dictionary, set it to the argument supplied
if assignment not in func._static:
func._static[assignment] = variable_or_default
# Return the static variable
return func._static[assignment]
def _example():
# Set/Define a static variable
i = static(0)
i += 1
print(i)
# Save the value for later use on the next call
static(i)
def _example_main():
for i in range(10):
_example()
if __name__ == '__main__':
_example_main()
@zinthose
Copy link
Author

The following example would run much more efficiently and is not too complicated to implement without the static function created above.

def test():
    i = 0 if not hasattr(test, '_static_i') else test._static_i

    i += 1
    print(i)

    test._static_i = i

if __name__ == '__main__':
    for i in range(10):
        test()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment