Hi,
there seems to be some confusion here as to what mutability is and how to test for it:
# below you are creating two separate objects, each with a different name
# pointing to it:
stim_H = visual.TextStim(win=win, text=u'H' ....)
stim_S = visual.TextStim(win=win, text=u'S' ....)
# now you also point a different name to the first object:
running_stim = stim_H
# i.e. it is still a single text stimulus object, but just has two
# different names pointing toward it.
# now immediately you redirect the name running_stim to point to
# the other stimulus:
running_stim = stim_S
# the current situation is that you have two TextStim objects, the first
# pointed at by one name (stim_H) and the second by two names
# (stim_S and running_stim)
# Nothing has changed just because you have introduced a third name
# into the mix, there are still two different objects, containing
# different content, and so this comparison will always return False:
print stim_S == stim_H
There is nothing PsychoPy-specific here: this is just the way that names refer to objects in Python. There is actually no mutation going on here at all. You can assign different additional names to objects, that doesn’t change them in any way (i.e. doesn’t mutate them).
So I’m not sure what the issue is. The code you wanted to apply (i.e. point the name running_stim
to one of several stimuli, and then calling running_stim.draw()
) should indeed work without any problem, and should be the expected behaviour in Python. And I think that is what you hope to happen?
PS when testing for identity of objects in Python, you probably want to use is
rather than ==
e.g. try this:
a = [1, 2, 3]
b = [1, 2, 3]
a == b # True (they contain the same values)
a is b # False (they aren't the same object)
b = a # assign both names to point to the same object
a is b # True (there is now only one object, with two names)
You can explore this using id(a)
and id(b)
to get the memory address of each object. Initially they are different (showing that they can’t be same object). After doing a = b
, id(a)
and id(b)
return the same number, indicating that each name is pointing to the same object (meanwhile, the object originally pointed to by the name b
, which now has no pointers to it, has in fact silently been erased from existence).
Perhaps the conceptual leap to make here is that names of objects aren’t the objects to which they refer. Think of an object as a real thing. You can stick as many post-it notes on such an object as you want (where each posit-it note is equivalent to a name). The names don’t change the object, and in fact you can peel off any of the notes at any time and stick them on a different object (which is what you do in your conditional drawing code). There is nothing special about which name you use to refer to an object, and in fact objects don’t even know their own name(s). The only restriction is that to continue existing, a Python object needs to have at least one name pointing to it (otherwise it is just floating unreachable in the vacuum of space).
Complications arise when you are dealing with that small number of Python classes (like strings and integers) that actually are immutable:
a = 'hello'
b = a
a == b # True
a is b # True - they point to the same object
a = a + 'bye' # a now points to a newly-created object,
# as the original is immutable
a is b # False: b still points to the original 'hello' object