What you're missing here is to understand the scope of variables. In Python (like in most programming languages), entering a function means you're entering a new scope, in which only the function's arguments, plus any global variables, are available.
When leaving the function, this scope (and any changes made to the variables in that scope) disappears. This is why you get this:
def add1(x):
x += 1
p = 0
add1(p)
print(p)
Will still show 0
.
The best and cleanest option here is to make your function return the new value. This way the function is what is called a "pure" function in that it operates only on its arguments, and produces a new value, without depending or affecting the global scope:
def add1(x):
return x + 1
p = 0
p = add1(p)
print(p)
For more info, you can read up https://python-textbok.readthedocs.io/en/1.0/Variables_and_Scope.html#variable-scope-and-lifetime
Hope this helps!