Why the same variable works differently based on location in the code?
In example P1, you are assigning the result of obj.matrix_world.to_translation() to a variable named objWorldPosition and then loop over all the frames. This does not change the value of the variable.
In the second example, you are asking the system, after each frame change, what is its position, which is different.
The equivalent between you and another human would be, for P1:

You: How far away are you from the tree?
Human: 5 steps.
You: Please walk 150 steps and for each step answer the question: &quot;what was the number you just told me?&quot;

P2:

You: How far away are you from the tree?
Human: 5 steps.
You: Please walk 150 steps and for each step answer the question: &quot;how far are you from the tree?&quot;

It's very logical to get the same answer each time in the first place, and a different one in the second.
This allows for example doing this
print(objWorldPosition - obj.matrix_world.to_translation())

to find how much your human moved from the time it started moving, that wouldn't be possible if objWorldPosition didn't store the variable.
That said, there is a way to do what you are trying to do, i.e. not having to call obj.matrix_world.to_translation() each time. You can assign a function to a variable instead of it's result (like telling your human,

Please walk 150 steps and for each step answer the question I just asked you

). This code does that:
#Example P2
import bpy
obj = bpy.data.objects[&quot;Empty&quot;]
objWorldPosition = obj.matrix_world.to_translation
sce = bpy.data.scenes[0]
for i in range(0, 150):
    sce.frame_set(i)
    print(objWorldPosition())

Notice the missing () in line 4 and the extra () in the last line. This means that the actual question (the &quot;call&quot;) is performed inside the loop, not before it.