This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Tutorial on Python Scopes and Namespaces uses confusing 'read-only' terminology
Type: Stage:
Components: Documentation Versions:
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: docs@python, ezio.melotti, georg.brandl, holdenweb, mjpieters, rhettinger
Priority: normal Keywords:

Created on 2016-02-27 09:15 by mjpieters, last changed 2022-04-11 14:58 by admin.

Messages (6)
msg260933 - (view) Author: Martijn Pieters (mjpieters) * Date: 2016-02-27 09:15
From the 9.2. Python Scopes and Namespace section:

> If a name is declared global, then all references and assignments go directly to the middle scope containing the module’s global names. To rebind variables found outside of the innermost scope, the nonlocal statement can be used; if not declared nonlocal, those variable are read-only (an attempt to write to such a variable will simply create a new local variable in the innermost scope, leaving the identically named outer variable unchanged).

This terminology is extremely confusing to newcomers; see https://stackoverflow.com/questions/35667757/read-only-namespace-in-python for an example. Variables are never read-only. The parent scope name simply is *not visible*, which is an entirely different concept. Can this section be re-written to not use the term 'read-only'?
msg260946 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2016-02-27 20:20
FWIW, the learners in my Python classes seem to find the words "read-only" to be helpful.  Also, I think "not visible" conveys the wrong mental model ("shadowed" being a little more accurate).  

I also disagree with saying that "variables are never read-only". In fact, unless declared "nonlocal", the namespace for the nested scope can't be written to; likewise, we also have dict proxies in classes that are specifically designed to be read-only; further, there are many read-only attributes in Python.

The current paragraph is succinct and accurate.   That said, there is no doubt that creative people can find ways to misread it, so I think  there is room to add an extra paragraph that elaborates on the rules:

1) variable *lookups* will search from locals to nested scopes to globals to builtins, stopping at the first match or raising NameError if not found; and, 

2) variable *writes* always go into locals unless explicitly declared as being in another namespace with "nonlocal" or "global".

The docs can't smooth this over by changing a single misinterpreted word.  One way or another, either in the tutorial or in a FAQ, users need to learn why x=1 doesn't write to an enclosing scope without a namespace declaration and why self.x+=1 can read a class variable, increment the value, and then write to an instance variable.  Learning this is fundamental to understanding the language and it can't be glossed over by saying that the word "read-only" was confusing.  Everyone gets what "read-only" means; instead, the challenge is to grapple with what the rules are and why the language behaves this way.
msg260947 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2016-02-27 21:35
I agree with Raymond.  IMHO the term "read-only" does a good job at conveying the fact that you can still access/read the value of the variable but you can't assign to it.  "read-only" is about /what/ you can do with the variable, even though it would also be good to clarify /why/ you can only read.
msg260985 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2016-02-28 20:06
I think rephrasing with "... can only be read" would keep the intended meaning, but avoid the problematic "the namespaces are readonly" meaning.
msg260996 - (view) Author: Martijn Pieters (mjpieters) * Date: 2016-02-29 08:56
+1 for "... can only be read". read-only can too easily be construed to mean that the variable cannot be set from *anywhere*, even the original scope. Another alternative would be "... is effectively read-only", but "... can only be read" is simpler.
msg260998 - (view) Author: Steve Holden (holdenweb) * (Python committer) Date: 2016-02-29 09:40
I don't agree there is any place for the term "read-only" in this document. A reader who doesn't understand it or seeks clarification is likely to end up at a page like https://en.wikipedia.org/wiki/Read-only. I submit that nowhere except the documentation under discussion are they likely to find any suggestion that a read-only variable can in fact be changed, and hence I regard the discussion as extremely misleading.

Surely it would be better to focus on the fundamental point here, which is that IN THE ABSENCE OF A global OR nonlocal DECLARATION, ASSIGNMENT BINDS IN THE LOCAL NAMESPACE in a function.

If this point is correctly emphasised it should then be relatively easy to explain that in the absence of such an assignment in the function body in question, the standard name resolution algorithm operates, and that the global and non-local declarations change the effect of assignments to operate on the namespace that is identified by the standard name resolution algorithm.

It's too easy to confuse newcomers, and there seems to be general agreement that this piece is confusing. I'll be happy to attempt a rewrite of this section if we can agree on the goals.
History
Date User Action Args
2022-04-11 14:58:28adminsetgithub: 70636
2016-02-29 09:41:00holdenwebsetnosy: + holdenweb
messages: + msg260998
2016-02-29 08:56:34mjpieterssetmessages: + msg260996
2016-02-28 20:06:34georg.brandlsetnosy: + georg.brandl
messages: + msg260985
2016-02-27 21:35:59ezio.melottisetnosy: + ezio.melotti
messages: + msg260947
2016-02-27 20:20:32rhettingersetnosy: + rhettinger
messages: + msg260946
2016-02-27 09:15:56mjpieterssetassignee: docs@python

components: + Documentation
nosy: + docs@python
2016-02-27 09:15:41mjpieterscreate