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.

2
  • 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() Commented Feb 28, 2014 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. Commented Feb 28, 2014 at 13:46

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

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.
docs.python.org/3/reference/…: "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."
Does it mean that the nearest enclosing scope for a defined in the method body is a global namepace (skipping class)?
@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).
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.

2 Comments

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 ah indeed. Sorry about that.