I would expect it to print "me too", because I would expect the assignment in the function to change the global variable when it is called, not create another variable.
Your expectation does not match the best practices that language designers have converged on in this day and age. No one can keep up with all the variables outside a given function, and it’s way to easy to cause confusing, untraceable side effects. In almost every language, variables introduced in methods like this will be lexically scoped when the contrary is not otherwise indicated.
(Some of the older languages do differ, and usually best practices in those languages include running linters that yell at you to use explicit scopes.)
Then the function should not use the global variable at all without explicitly indicating it. Printing 2 different variables when referring to a singular one is not great behavior, and passes the smell test for "confusing, untraceable" side effect to me. There should also be a different syntax for initializing a variable and changing a variable value, so that your intention is obvious.
I can see the point a bit of added safety of basically defaulting to a constant when declaring global variables, although since I use older languages (but not python), I have not run into that. I do find it humorous that the global variable is semi-protected in python, while the variable type is not.
> Then the function should not use the global variable at all without explicitly indicating it
Generally you use `global` to handle this.
> I do find it humorous that the global variable is semi-protected in python, while the variable type is not.
It's not, there are no differences between them. Bindings (names) are captured like most other languages, and you're free to overwrite them if you wish.
In your example you bind a new string to an existing name. I think it's pretty expected that this wouldn't suddenly change the global object to a local one, that would be madness.
But you're free to update the object _referenced_ if it's mutable:
Assigning is different than appending, and is the case with a syntax ambiguity. But I'm also not a big fan of the implicit `global` in your example if it's not always implicit.
Fine, we want a test by using `global` to make sure we are doing what we intend when we assign, especially since I see python does not even have true constants so there is a basic lack of safety there. There should also be similar tests before passing every variable with the same name through our function and treating a single name as a list of references without a keyword `all` or similar. Or changing the type of a variable without explicit casting.
To me that lack of continuity just makes a language feel idiomatic and buggy.
I believe Wolfram Mathematica has this terrible global scoping by default.
It's not exactly a language that programmers refer to often, as it's not really general purpose, but I had to do some work with MRI data in it and I hated it mostly due to the scoping.
An "I spent a decent bit of time rewriting the entire lab's codebase in python" type of hate.
I like that better (and I realize I might be alone!). But I don't like that you can declare a global variable in a local function by omitting the var. It's a similar needless ambiguity and frankly much more prone to errors than the python local variable initialization. At least there is strict mode.