Статический член функции в Python?
Возможный дубликат:
Статические переменные класса в Python
Что такое эквивалент Python для статических переменных внутри функции?
Как использовать статические поля в Python?
Например, я хочу подсчитать, сколько раз функция была вызвана - как я могу это сделать?
Ответы
Ответ 1
Если вы хотите подсчитать, сколько раз был вызван метод, независимо от того, какой экземпляр его назвал, вы можете использовать член класса следующим образом:
class Foo(object):
calls=0 # <--- call is a class member
def baz(self):
Foo.calls+=1
foo=Foo()
bar=Foo()
for i in range(100):
foo.baz()
bar.baz()
print('Foo.baz was called {n} times'.format(n=foo.calls))
# Foo.baz was called 200 times
Когда вы определяете calls
следующим образом:
class Foo(object):
calls=0
Python помещает пар ключ-значение ( "вызовы", 0) в Foo.__dict__
.
Он может получить доступ с помощью Foo.calls
.
Экземпляры Foo
, такие как foo=Foo()
, могут получить к нему доступ с помощью Foo.calls
.
Чтобы назначить новые значения Foo.calls
, вы должны использовать Foo.calls = ...
.
Экземпляры не могут использовать Foo.calls = ...
, потому что это заставляет Python размещать новую и другую пару ключ-значение в Foo.__dict__
, где хранятся члены экземпляра.
Ответ 2
Вот пример, подсчитывающий количество вызовов всех объектов одного и того же класса:
class Swallow():
i = 0 # will be used for counting calls of fly()
def fly(self):
Swallow.i += 1
И это доказательство:
>>> a = Swallow()
>>> b = Swallow()
>>> a.fly()
>>> a.i
1
>>> Swallow.i
1
>>> b.fly()
>>> b.i
2
>>> Swallow.i
2
чтобы вы могли прочитать его, указав имя объекта или имя класса.
Ответ 3
Здесь декоратор добавляет подсчет к функции.
import functools
def count_calls(func):
@functools.wraps(func)
def decor(*args, **kwargs):
decor.count += 1
return func(*args, **kwargs)
decor.count = 0
return decor
Использование:
>>> @count_calls
... def foo():
... pass
...
>>> foo.count
0
>>> foo()
>>> foo.count
1
Ответ 4
Вот один простой способ сделать это:
def func():
if not hasattr(func, 'counter'):
func.counter = 0
func.counter += 1
counter = 0 # Not the same as `func.counter`
print(func.counter)
Или, если вам не нравится, если он выполняется при каждом вызове, вы можете сделать:
def func():
func.counter += 1
print(func.counter)
func.counter = 0