0

What does read-value mean in the context of names?

In [1]: def outer():
   ...:     x=1
   ...:     def inner():
   ...:         print x
   ...:     inner()
   ...:

In [2]: outer()
1

Like in the above example x in not the namespace of inner(). Do variables in namespaces have types such as read-only/ writeable etc?

Quoting official docs: "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)."

Reference: https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces (5 th last paragraph)

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Abhishek Bhatia
  • 9,404
  • 26
  • 87
  • 142

1 Answers1

3

No, variables don't have 'properties' like read-only or write. The namespace implementation may disallow direct manipulation, but that's something entirely different.

The nonlocal and global statements let you override the scope of a variable; without these Python will make a name local if it is being bound to. Binding actions include assignment, for loop, with .. as and except .. as statement targets, function arguments and imports. Changing the scope doesn't alter if a variable is read-only or not, it merely changes the scope that manages the variable. nonlocal means it'll be stored in a parent scope and made a closure.

The term read-only used by the quote you found is very misleading; assignment clearly still alters the local variable. The presence of local doesn't make the same name in the parent scope not writable, it is simply not visible in the innermost scope. It's disappointing that this is from the official tutorials; I've reported a bug to see this corrected.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • I have trouble fitting together the namespace and read-only. Are you saying namespaces are only relevant for binding? – Abhishek Bhatia Feb 27 '16 at 09:06
  • 1
    @AbhishekBhatia: there is no such thing as read-only. The quote you found is very misleading. I'm disappointed that this is from the Python tutorial. – Martijn Pieters Feb 27 '16 at 09:06
  • Thanks! Are there good references to what happens what variable is read. What is the order of scope followed then. Check edit in question for cause of confusion. – Abhishek Bhatia Feb 27 '16 at 09:40
  • See [Short Description of Python Scoping Rules](http://stackoverflow.com/q/291978) for the scope rules. – Martijn Pieters Feb 27 '16 at 09:41
  • 1
    The warning is entirely unrelated. It is better to put the `global x` statement first in a function, so anyone reading the code sees it first. Because it affects the *whole* scope it doesn't really matter where you put it in the function. – Martijn Pieters Feb 27 '16 at 09:43
  • Thanks, that makes sense. – Abhishek Bhatia Feb 27 '16 at 09:44
  • I am not sure if I understand what you mean by "nonlocal means it'll be stored in a parent scope and made a closure." To me in the example, `x` is already in the closure of `inner()`. What has `non-local` got to do with it? – Abhishek Bhatia Feb 27 '16 at 10:06
  • @AbhishekBhatia: you didn't assign to `x`, so yes, it'll be a non-local (a closure) by default. But if you tried to assign to it in `inner()`, but want to keep it a non-local, you need to mark it as such explicitly. – Martijn Pieters Feb 27 '16 at 10:07
  • On the same page in foot-note : `Except for one thing. Module objects have a secret read-only attribute called __dict__ which returns the dictionary used to implement the module’s namespace; the name __dict__ is an attribute but not a global name. ` It seems to state read-only again. – Abhishek Bhatia Feb 27 '16 at 11:29
  • 1
    @AbhishekBhatia: that's because the **attribute** is read-only. You cannot replace it. You can't do `import module; module.__dict__ = something_else`. Attributes are not variables in the sense of scoping rules. – Martijn Pieters Feb 27 '16 at 11:34