Вопрос-Ответ

What is the Python equivalent of static variables inside a function?

Каков Python-эквивалент статических переменных внутри функции?

Каков идиоматический Python-эквивалент этого кода на C / C ++?

void foo()
{
static int counter = 0;
counter++;
printf("counter is %d\n", counter);
}

в частности, как реализовать статический элемент на уровне функции, в отличие от уровня класса? И меняет ли что-нибудь помещение функции в класс?

Переведено автоматически
Ответ 1

Немного наоборот, но это должно сработать:

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

Если вы хотите, чтобы код инициализации счетчика находился вверху, а не внизу, вы можете создать декоратор:

def static_vars(**kwargs):
def decorate(func):
for k in kwargs:
setattr(func, k, kwargs[k])
return func
return decorate

Затем используйте код, подобный этому:

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

К сожалению, вам все равно потребуется использовать префикс foo..

(Предоставлено: @ony)

Ответ 2

Вы можете добавить атрибуты к функции и использовать ее как статическую переменную.

def myfunc():
myfunc.counter += 1
print myfunc.counter

# attribute must be initialized
myfunc.counter = 0

В качестве альтернативы, если вы не хотите настраивать переменную вне функции, вы можете использовать hasattr(), чтобы избежать AttributeError исключения:

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

В любом случае статические переменные встречаются довольно редко, и вам следует найти для этой переменной место получше, скорее всего, внутри класса.

Ответ 3

Можно также рассмотреть:

def foo():
try:
foo.counter += 1
except AttributeError:
foo.counter = 1

Рассуждения:


  • много питоновского ("просить прощения, а не разрешения")

  • используйте exception (генерируется только один раз) вместо if перехода (подумайте об исключении StopIteration)

Ответ 4

Многие люди уже предлагали протестировать 'hasattr', но есть более простой ответ:

def func():
func.counter = getattr(func, 'counter', 0) + 1

Никаких попыток / исключений, никакого тестирования hasattr, просто getattr с значением по умолчанию.

python