4

I'm typing in an interactive mode the following code:

class A:
    a=42
    def foo():
        nonlocal a

but I've a SyntaxError: no binding for nonlocal 'a' found. But I'm expected that the result of resolution nonlocal a will be 42, because the nearest enclosing scope for this method is a class block.

  • I know this doesn't fix your problem, and maybe this is a result of the simplified version of your code here, but couldn't you accomplish the same thing by making ```a``` a class attribute? (referring to it as ```self.a``` and passing ```self``` as an argument to ```foo()``` – wnnmaw Feb 28 '14 at 13:44
  • @wnnmaw I know that method's code can't access to a class namespace. But I'm interested in how nonlocal does work. –  Feb 28 '14 at 13:46

2 Answers2

4

Class scope are handled in a special way by Python: When looking for names in ecnlosing scopes, class scopes are skipped.

To access a name from the class scope either use self.a to look up via the instance or A.a to look up via the class.

See The scope of names defined in class block doesn't extend to the methods' blocks. Why is that? for a rationale for this behaviour.

Community
  • 1
  • 1
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • That is what I want to know, thanks :). But can you get a referene to a `python reference manual` about names resolution? I can find only `When a name is used in a code block, it is resolved using the nearest enclosing scope.` –  Feb 28 '14 at 13:51
  • http://docs.python.org/3/reference/executionmodel.html#naming-and-binding: "The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods." – Sven Marnach Feb 28 '14 at 13:52
  • Does it mean that the nearest enclosing scope for `a` defined in the method body is a global namepace (skipping class)? –  Feb 28 '14 at 14:02
  • 1
    @DmitryFucintv: Yes, it does. But `nonlocal` can't be used to refer to names in the global scope. Use `global` for that (if you really have to). – Sven Marnach Feb 28 '14 at 14:43
0

What you're doing is creating a class which has a class attribute a, with a default value of 42. You can refer to that attribute by A.a. If you want to use it within the class, use self.a.

msvalkon
  • 11,887
  • 2
  • 42
  • 38
  • I believe the OP is not using 2.x. The 2.x error message is `SyntaxError: invalid syntax`. The 3.x error message is `SyntaxError: no binding for nonlocal 'a' found`, which is what the OP has. – Kevin Feb 28 '14 at 13:58
  • @Kevin ah indeed. Sorry about that. – msvalkon Feb 28 '14 at 14:20