In Python 3 your code would work, but in Python 2 there is some wrapping that takes place when methods are looked up.
Class vs Instance
class level: storing counter
with the function (either directly, or by using a mutable default) effectively makes it a class level attribute as there is only ever one of the function, no matter how many instances you have (they all share the same function object).
instance level: to make counter
an instance level attribute you have to create the function in __init__
, then wrap it with functools.partial
(so it behaves like a normal method), and then store it on the instance -- now you have one function object for every instance.
Class Level
The accepted practice for a static-like variable is to use a mutable default argument:
class foo(object):
...
def bar(self, _counter=[0]):
_counter[0] += 1
return _counter[0]
If you want it to be prettier you can define your own mutable container:
class MutableDefault(object):
def __init__(self, start=0):
self.value = start
def __iadd__(self, other):
self.value += other
return self
def value(self):
return self.value
and change your code like so:
class foo(object):
def bar(self, _counter=MutableDefault()):
_counter += 1
return _counter.value
Instance level
from functools import partial
class foo(object):
def __init__(self):
def bar(self, _counter=MutableDefault(1)): # create new 'bar' each time
value = _counter.value
_counter += 1
return value
self.bar = partial(bar, self)
Summary
As you can see, readability took a serious hit when moving to instance level for counter
. I strongly suggest you reevaluate the importance of emphasizing that counter
is part of bar
, and if it is truly important maybe making bar
its own class whose instances become part of the instances of foo
. If it's not really important, do it the normal way:
class foo(object):
def __init__(self):
self.bar_counter = 0
def bar(self):
self.bar_counter += 1
return self.bar_counter
counter
be class level (all instances share the current count), or instance level (each instance would start at 1) ? – Launderettecounter
should be instance level – Perdition