global is necessary
When I started out programming in Python, I didn't really like
global. For a long time I considered it unaesthetic, annoying,
and on the whole an irritating wart of the bytecode implementation. As I mentioned recently,
I have come around to a different view of
global, and it goes like
If you want to have both global variables and lexically scoped local variables, you have to be able to tell whether a given name being assigned to in a function is a local or a global variable at the time that the function is being defined. Assuming that you want as much as possible of this to be implicit for various reasons, there are three relatively reasonable choices that I can think of:
- you must declare globals explicitly; otherwise names are local.
- you must declare locals explicitly; otherwise names are global.
- the decision is made implicitly by what global names already exist when the function is being defined; a name that exists globally is taken as a global variable, and otherwise the name is taken as a local variable.
(If a name is never assigned to within a function but only read from, it's either a global variable or a 'use of an undefined value' error. Python opts to consider it a global variable.)
The third option is fragile (and un-Pythonic). This leaves you with a
choice between the first and the second options, and either way you are
going to need a keyword for it. Python makes the decision that writing
to global variables will be rare and so it forces you to declare them
explicitly; local variables, the common case, are handled implicitly. So
global, because having
local instead would be worse (and
having neither would be much worse).
(This decision might be either a pragmatic one, based on what was expected to be common, or a philosophical choice to make global variables more inconvenient in the hopes of making them less common. I don't know the Python history involved, so I have no idea which it was.)
Other languages make different choices here, sometimes for philosophical reasons that come down on the other side and sometimes just for historical ones (eg, if they started out without local variables or lexical scoping at all).
Sidebar: the many problems with the fully implicit option
The core problem with the fully implicit option, why it is fragile in many ways, is that it makes the meaning of a function dependent on its surrounding context. You can't just read a function and know what it does and what it manipulates; instead you have to know what global names exist when the function is defined.
One consequence of this is that anything that changes what global names are defined can change the meaning of the function. In a language like Python where function definition is an ordinary executable statement, one done immediately when encountered, merely moving a function definition forward or backwards inside a file could change the function's meaning even without any other code changes (as you move it before or after where global names are created or even deleted).