Let's output some things:
class Test:
pos = [0, 0]
actions = []
def bar(self, target):
for i in target:
print(f"i={i} id={id(i)}")
def _():
print(f"_i={i} _id={id(i)}")
print(i, end="")
self.actions.append(_)
Output:
i=a id=2590411675120
i=b id=2590411458416
i=c id=2590411377456
i=d id=2590411377200
_i=d _id=2590411377200
d_i=d _id=2590411377200
d_i=d _id=2590411377200
d_i=d _id=2590411377200
See, the i in def _ overrides every time for loop iterates and eventually last value is what you get.
How to solve this? Pass i as an argument:
from functools import partial
class Test:
pos = [0, 0]
actions = []
def bar(self, target):
for i in target:
print(f"i={i} id={id(i)}")
def _(i):
print(f"_i={i} _id={id(i)}")
print(i, end="")
self.actions.append(partial(_, i))
Output:
i=a id=2618064721392
i=b id=2618064504688
i=c id=2618064423728
i=d id=2618064423472
_i=a _id=2618064721392
a_i=b _id=2618064504688
b_i=c _id=2618064423728
Let's remove print statements now:
from functools import partial
class Test:
pos = [0, 0]
actions = []
def bar(self, target):
for i in target:
def _(i):
print(i, end="")
self.actions.append(partial(_, i))
foo = Test()
foo.bar("abcd")
for i in foo.actions:
i()
# Output: abcd
ivariable.actionsin__init__or it will be done at the class level, which is shared for allTest, not forfoowhich is a single instance ofTest.