When using a class, I can preserve a state using a property:
class Hello:
def __init__(self):
self.hello = 1
def add_one(self):
if self.hello < 3:
self.hello += 1
else:
self.hello = 1
h = Hello()
for _ in range(5):
h.add_one()
print(h.hello)
# output
2
3
1
2
3
In between calls to h.add_one()
, the state is preserved in h.hello
.
Is there an equivalent mechanism in functions? Something along the lines of
def add_one():
a_special_kind_of_variable_which_is_not_reinitialized hello
if hello_is_not_initialized:
hello = 1
if hello < 3:
hello += 1
else:
hello = 1
return hello
for _ in range(5):
print(add_one())
# same output as above
Python does not have C-style static variables. However, you can simulate them with closures.
def make_add_one():
x = 0
def _():
nonlocal x
if x < 3:
x += 1
else:
x = 1
return x
return _
add_one = make_add_one()
for _ in range(5):
print(add_one())
There is a duality between objects (data with functions) and closures (functions with data); compare to the class defined by Carcigenicate (slightly modified):
class AddOne:
def __init__(self):
self.hello = 0
def __call__(self):
if self.hello < 3:
self.hello += 1
else:
self.hello = 1
return self.hello
add_one = AddOne()
for _ in range(5):
print(add_one())
One can see the following correspondences:
AddOne
↔ outer function make_add_one
AddOne()
↔ inner function make_add_one()
AddOne().hello
↔ non-local variable hello
inside make_add_one