From: Bruce S. <bas...@un...> - 2002-10-04 12:15:11
|
A VPython user sent me a small program that behaved oddly, and I thought I should share my analysis, since it involves an aspect of Python that is subtle and may be missed in early study of the language. Fortunately it rarely bites students writing computational physics programs! Early in the program the user said "rinitial = ball.pos" which means "assign an additional name to ball.pos, so that in the future one can refer to the ball's position either by the label (name) ball.pos or the label (name) rinitial". You can have lots of names pasted onto the same thing. The puzzle for the user was that later in the program (after moving the ball around), printing rinitial showed the new value of ball.pos, not the initial value. This multiple labeling has consequences only with "mutable" objects such as lists -- objects whose values can be changed in situ. For example, if you say "a = 5" and then "b = a", and then say "a = 7", b will still have the value 5. When you assign 7 to a, you create a new object ("7") and attach the label "a" to it, so b continues to be a label for the object "5". But with "rinitial = ball.pos", you can actually change ball.pos without creating a new object. For example, you might say "ball.pos.y = 7" in which case the 2nd element in the ball.pos list has changed (without affecting the other two elements). Since rinitial is a label for ball.pos, printing rinitial shows you the new value of ball.pos. A list such as [1,2,3] is mutable. The Visual vectors are mutable. A 'tuple' such as (1,2,3) is not mutable. Constants such as 3 or pi or a string such as 'cat' are not mutable. Needless to say, it took me a while to pay attention to "mutability" as an important property of Python objects! Bruce |