def fun(x):
x += 1 => Adds 1 to the x from the method argument
return x => Returns the new value of x
x = 2
x = fun(x + 1) => Call the function as fun(2 +1) which returns 3 + 1 and assigns to the variable x
print(x) => Prints the latest x value which is 4.
To further clarify, let the change the program a little bit without affecting the result of the program:
def fun(y):
y += 1
return y
x = 2
x = fun(x + 1)
print(x)
Here, the variables used inside the function are totally different than the one that is used to call the function.
So, The value of x is updated only because the functions returns the updated value of x, which is then assigned to x as x = func(x), It has nothing to do with the variable names.