Python статические переменные функции

Локальные статические переменные и константы в функциях Python

Если в функциях необходимы константы или значения, неизменяющиеся между вызовами, то их можно определить в глобальной области видимости (например, в начале модуля), а также не забыть упомянуть в директиве global этой функции переменные, которым будут присваиваться значения. Но они не будут защищены от изменений кодом, находящимся вне функции. А также, при разросшемся коде, может возникать некоторое неудобство при перемещении по тексту между переменными/константами и собственно функцией.

Для констант напрашивается простое решение — сделать их параметрами функции с требуемыми значениями по умолчанию. Их можно даже изменять в теле функции, но при следующем вызове значение будет восстанавливаться.

Для переменных типа списков, словарей и т.п. можно поступить также, их содержимое будет сохраняться между вызовами. Но если необходимо сохранять значения простых (int, str и т.п.) переменных между вызовами — то их придётся разместить в списке или словаре, являющемся значением по умолчанию определённого параметра функции. Но конечно удобству доступа к ним теперь не позавидуешь. Однако, облегчить его может доступ к элементам словаря в стиле Javascript. Возможные варианты реализации таких словарей есть здесь, здесь, здесь. Для себя ограничился следующим кодом:

class Storage(dict): __slots__ = () __setattr__ = dict.__setitem__ __delattr__ = dict.__delitem__ __getitem__ = dict.get __getattr__ = dict.get __getnewargs__ = lambda self: getattr(dict,self).__getnewargs__(self) __repr__ = lambda self: '' % dict.__repr__(self) __getstate__ = lambda self: None __copy__ = lambda self: Storage(self) 

Понимаю, что для данной цели он тоже избыточный, но из осторожности больше ничего выбрасывать не стал.
И примерно так им пользовался (в примере особого смысла не искать):

def read_serial(prorej=round(per_ind / per_ser), imp_s_l_m=60 / imp_na_l, imp_queue=[(0, 0)] * 7, # time.time() o=Storage(imp_cntr_glob=0, ser_cntr=0, i=0)): . o.ser_cntr += 1 # o["ser_cntr"] += 1 . o.imp_cntr_glob += imp # o["imp_cntr_glob"] += imp . if o.ser_cntr % prorej: # if o["ser_cntr"] % prorej: . imp_cur = o.imp_cntr_glob, time.time() . dimp, dt = map(lambda a, b: a - b, imp_cur, imp_queue.pop(0)) imp_queue.append(imp_cur) . dimp, dt = map(lambda a, b: a - b, imp_cur, imp_queue[o.i]) imp_queue[o.i] = imp_cur o.i = (o.i + 1) % len(imp_queue) . v = int(dimp / dt * imp_s_l_m) . 

Источник

Читайте также:  Cpp свой тип функция

Использование статических переменных в функциях в Python

Часто разработчики, привыкшие к таким языкам программирования как C/C++, сталкиваются с необходимостью использовать статические переменные внутри функций при переходе на Python. В C/C++ статическая переменная внутри функции сохраняет свое значение между вызовами функции, что может быть очень полезно.

Возьмем в качестве примера следующий код на C++:

В этом коде переменная counter увеличивается на 1 при каждом вызове функции foo() , и значение counter сохраняется между вызовами.

Реализация статических переменных в Python

В Python нет прямого аналога статическим переменным в функциях, как в C/C++. Однако, есть несколько способов реализовать подобное поведение.

Использование атрибутов функции

Один из способов — использовать атрибуты функции. В Python функции — это объекты, и у них могут быть атрибуты. Вот пример кода, который демонстрирует это:

def foo(): if not hasattr(foo, "counter"): foo.counter = 0 foo.counter += 1 print("counter is", foo.counter)

В этом коде foo.counter является атрибутом функции foo . При первом вызове функции атрибут counter инициализируется значением 0, а затем при каждом вызове функции foo значение counter увеличивается на 1.

Использование генераторов

Другой способ — использовать генераторы. Генераторы в Python — это специальный тип функций, которые сохраняют свое состояние между вызовами. Вот пример кода, который демонстрирует это:

def foo(): counter = 0 while True: yield counter counter += 1 f = foo() for _ in range(5): print("counter is", next(f))

В этом коде foo — это генератор, который при каждом вызове функции next возвращает значение counter и затем увеличивает его на 1.

Использование замыканий

Третий способ — использовать замыкания. Замыкание в Python — это функция, которая имеет доступ к переменным из своей области видимости, даже после того, как эта область видимости исчезла. Вот пример кода, который демонстрирует это:

def foo(): counter = [0] def inner(): counter[0] += 1 print("counter is", counter[0]) return inner f = foo() for _ in range(5): f()

В этом коде foo возвращает функцию inner , которая имеет доступ к переменной counter из области видимости функции foo . При каждом вызове функции f (которая теперь ссылается на inner ) значение counter увеличивается на 1.

Читайте также:  Язык html вставка графики

Источник

Python static variable in a function | Example code

You can make static variables inside a function in many ways in Python. If declaring a static variable in a function means variable throughout the lifetime of the program.

Python static variable in a function examples

Simple 3 example code for it:-

Add attributes to a function

You can add attributes to a function, and use it as a static variable. Count how many times functions have been called using a static variable.

def foo(): foo.counter += 1 print("Counter is %d" % foo.counter) foo.counter = 0 foo() foo()

Python static variable in a function

Initialization code at the top using decorator

If you want the counter initialization code at the top instead of the bottom, you can create a decorator:

def static_vars(**kwargs): def decorate(func): for k in kwargs: setattr(func, k, kwargs[k]) return func return decorate # Then use the code like this: @static_vars(counter=0) def foo(): foo.counter += 1 print("Counter is %d" % foo.counter) foo()

Output: Counter is 1

Use hasattr()

Alternatively, if you don’t want to set up the variable outside the function, you can use hasattr() to avoid an AttributeError exception:

def myfunc(): if not hasattr(myfunc, "counter"): myfunc.counter = 0 # it doesn't exist yet, so initialize it myfunc.counter += 1 return myfunc.counter print(myfunc()) print(myfunc())

Do comment if you have any doubts or suggestions on this Python variable topic.

Note: IDE: PyCharm 2021.3.3 (Community Edition)

Windows 10

Python 3.10.1

All Python Examples are in Python 3, so Maybe its different from python 2 or upgraded versions.

Источник

Оцените статью