1

Consider the following code:

from enum import Enum

class A(object):
    class B(object):
        blah = "foo"
        derp = "bar"

    class SubA(object):
        def __init__(self):                                                                                                                                                                                                            
            self.value = B.derp

This raises a NameError

>>> A.SubA()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "test.py", line 10, in __init__
    self.value = B.derp
NameError: name 'B' is not defined

On the other hand, replacing B.derp with A.B.derp makes the code work as desired.

Why does Python's scoping resolve this in the way it does, and why should this make sense in Python's design?

2 Answers 2

4

As described in PEP 227, the class body's scope is not available from inside other scopes nested inside it. So the reason you get a NameError for B in your example is the same reason you get a NameError in this case:

class Foo(object):
    x = 88
    def foo(self):
        print(x)

Functions defined in the class body (i.e., methods) don't have access to the class body scope; neither do nested classes (or functions nested inside those).

A.B.derp works because A is in global scope, which is always accessible.

However, note that even A.B.derp won't work if you try to use it directly in the class body:

class A(object):
    class B(object):
        derp = 88
    class SubA(object):
        stuff = A.B.derp

This won't work because the line referring to A.B.derp is executed during the process of creating A, so A doesn't exist yet and can't be referenced.

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

Comments

1

Although classes define a new namespace, they don't create a scope for names used inside of bodies of methods. While referring to them the names have to be fully qualified. That what self.something or cls.something are for.

Try using a fully qualified name like A.B.something. A is in the same namespace as B but not in the same variable scope.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.