In your first test, in your launch function, the test
variable is recreated, with no link to the global function. It's a particularity of python.
If you wanted to change the global function you should have done like this :
def launch():
global test
test = 'F'
With your second test, test
is a dictionary.
And yes, when you change a dictionary in a function without declaring it as a global variable, it changes the dictionary outside of the function as well.
If you want to know the real reason, it's way more complicated if you don't know C language... Python was programmed in C (for CPython at least), and in C, managing variables is very different than in Python.
In C, when you want to modify a variable in a function, you have to give to the function the memory address of the variable as a parameter (that variable is called a Pointer).
If you don't give the pointer of your global variable to the function where you want to modify it, it won't work.
When your launch
function was called in your first example, test wasn't modified, because as you haven't declared test
as global, python hasn't given the pointer of test
to the launch
function (only its value).
When you use dictionaries, Python will also give the value of the dictionary, but it will be a pointer to its elements. So you will be able to modify them.
That's why you can modify the elements in the dictionary, but you can't modify the dictionary. Example :
a = {"a":123, 'b':456}
def modif():
a = {"aa":123}
modif()
print(a)
results in:
{'a': 123, 'b': 456}
So the dictionary hasn't been modified. It works the same way with the lists (and I suppose with every iterable that support item assignment)
I tried to simplify, it's more complicated in reality, but it may teach you some thing I hope.