[Python-ideas] global and nonlocal with atributes

Steven D'Aprano steve at pearwood.info
Sun May 5 08:41:02 CEST 2013


On 05/05/13 03:47, João Bernardo wrote:
> Hi,
> I couldn't find whether this was proposed or not, but seems interesting to
> me:
>
> Whenever there's an assignment inside a big function, we think it is a
> local variable, but it could have been defined as global on top and that
> can mess things up if not checked.

Are you suggesting that checking the top of the function for a global declaration is so difficult that Python needs special syntax to fix that?

Your description of the problem that this new syntax will fix is based on two design flaws:

* it's a function using global variables;

* it's a BIG function;

Both of which are signs that the function should be re-written, not that the language needs a band-aid to fix some of the pain from poor-quality code. A well-designed language should encourage good code. Both global variables and large monolithic functions are signs of potentially bad code.



> So, I why not have attribute syntax on "global" and "nonlocal" keywords?
[...]
> x = 10
> def increment():
>      global.x += 1


As Python exists today, this would be a big change for very little benefit. global is a keyword, not an object, so the language would need to allow *some* keywords to be used as if they were objects, but not all keywords:

y = global.x + 1  # allowed

y = for.x + 1  # not allowed


Even though here global looks like it is an object, it isn't, since this will cause a SyntaxError:

y = global  # global what?


Of course, global must remain a keyword, for backwards compatibility with code writing things the old way.

However, I can see some merit in your suggestion, for Python 4000 when backwards compatibility is no longer an issue. Get rid of the global and nonlocal declarations, and instead introduce two, or possibly three, reserved names, similar to None:

globals
nonlocals
builtins

each of which is a true object. Now globals.x is equivalent to globals()['x'], and there is no need for a globals() function or a global keyword.

Obviously I have not thought this through in any great detail. For instance, there is only a single None object in the entire Python application, but every module will need its own globals object, and every nested function its own nonlocals object. Maybe this idea is only superficially interesting and no good in practice. But we've got plenty of time to think about it.



[...]
> That way you can have both "global.x", "nonlocal.x" and "x" variables
> without conflict.
>
> x = 10
> def f(x):
>     def g():
>         # how can I set both "x" variables inside here?

You can't, and you shouldn't need to. How hard is it for you to use a different name for the global and the local? There are billions of possible names to choose from, why use the same name for both? Again, your proposal encourages poorly written code. Good language features should encourage good code, not bad code. It's actually a good thing that using global variables is slightly inconvenient, as that helps discourage people from using them.



-- 
Steven



More information about the Python-ideas mailing list