Mar-02-2017, 10:23 PM
Disclaimer: its only my very vague interpretation
I think that you are wrong when assuming "func has no variable". All of your functions have a local variable x. x in a function body is not same as x outside the body of the function - in a local scope (inside the function) x denotes function's x and not outside one (when you use same names for variables in different scopes, a variable in inner scope "shadows" outside one and it gets confusing ...).
Variables in python are passed by assignment, your outside x references to some object and that reference is "copied" to your local x. A function cannot change outside x's reference - it will point to the same object regardless of function's trying. But if that object is mutable, the function can modify it.
The identity of the variable (address) can be obtained with built-in function id(), so its possible to "follow" what is happening.
Example function - same as your first one, with print to show variable's id.
Things are little different when an object is immutable (cant be "changed").
Example func, same as your second one, again with print to show variable's id.
I think that you are wrong when assuming "func has no variable". All of your functions have a local variable x. x in a function body is not same as x outside the body of the function - in a local scope (inside the function) x denotes function's x and not outside one (when you use same names for variables in different scopes, a variable in inner scope "shadows" outside one and it gets confusing ...).
Variables in python are passed by assignment, your outside x references to some object and that reference is "copied" to your local x. A function cannot change outside x's reference - it will point to the same object regardless of function's trying. But if that object is mutable, the function can modify it.
The identity of the variable (address) can be obtained with built-in function id(), so its possible to "follow" what is happening.
Example function - same as your first one, with print to show variable's id.
def func(local_x): print("local_x points to: {}, its value is: {}".format(id(local_x), local_x)) local_x[1] = 42 print("local_x points to: {}, its value is: {}".format(id(local_x), local_x))And test run:
Output:>>> x = [1, 2, 3]
>>> id(x)
139841538326408
>>> func(x)
local_x points to: 139841538326408, its value is: [1, 2, 3]
local_x points to: 139841538326408, its value is: [1, 42, 3]
>>> x
[1, 42, 3]
>>> id(x)
139841538326408
You can see that both x and local_x always referenced the same object and that object was modified.Things are little different when an object is immutable (cant be "changed").
Example func, same as your second one, again with print to show variable's id.
def func_imm(local_x): print("local_x points to: {}, its value is: {}".format(id(local_x), local_x)) local_x = 7 print("local_x points to: {}, its value is: {}".format(id(local_x), local_x))And test run:
Output:>>> x = 3
>>> id(3)
94008579423936
>>> func_imm(x)
local_x points to: 94008579423936, its value is: 3
local_x points to: 94008579424064, its value is: 7
>>> x
3
>>> id(x)
94008579423936
local_x referenced same object (3) as outside x till assignment. Integers are immutable, the assignment could not change that object value, so instead of changing object it changed local_x's reference to object that represented 7. x still referenced 3 and as the function did not return local_x, it got "lost".