вторник, 29 апреля 2014 г.

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

Реализация на классе

Самый прямой и дубовый путь в питоне для этого, это использовать атрибуты классов. Т.е. хранить состояние в атрибуте класса, в __init__() его инициализировать, а в вызовах методов делать с этим атрибутом то, что нам нужно.

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

1 class A():
 2 
 3     def __init__(self):
 4         self.cnt = 0
 5 
 6     def f(self):
 7         self.cnt += 1
 8         return self.cnt
 9 
10 a = A()
11 
12 print " Class A testing"
13 print a.f()
14 print a.f()
15 print a.f()
16 
17 > Class A testing
18 > 1
19 > 2
20 > 3

Реализация внутри функции

Предыдущий пример работает. Но есть и недостатки. Нужно определять класс, создавать его объект, вызвать метод объекта. А нельзя ли попроще, так, чтобы все было спрятано внутри функции и нам не нужно бы было заморачиваться с тем, что не относится собственно к нужному нам эффекту?

Можно!

В питоне все является объектом, в том числе и функция. И у функции могут быть атрибуты. Эти атрибуты могут создаваться во время выполнения и храниться все время, пока существует программа.

Попробуем реализовать следующий план, например для того же счетчика вызовов:

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

Код:
1 def f():
 2     try:
 3         f.a += 1
 4     except AttributeError:
 5         f.a = 0
 6     return f.a
 7 
 8 print " Function f() testing"
 9 print f()
10 print f()
11 print f()
12 
13 > Function f() testing
14 > 1
15 > 2
16 > 3
http://blog.swlogic.eu/2011/06/19/python-staticheskie-peremennyie-v-funktsiyah/ 

1 комментарий: