0

In Python (2.7) one can use nested class declarations which is sometimes handy to organise local classes.

However, I can't figure out how to reference a class in a parent class so I can derive from it.

A minimal example is this:

class A(object):
    class B(object):
        pass

    class C(object):
        class D(A.B): # <-- fails with "NameError: name 'A' is not defined"
            pass

How can I make class D derive from class B given the nested structure of the class declaration?

1 Answer 1

2

You can't. You can't reference it as A.B, because A is not yet defined (you are in the middle of the definition), and you can't reference it as B because as per PEP 227, names in class scope are not accessible:

Names in class scope are not accessible. Names are resolved in the innermost enclosing function scope. If a class definition occurs in a chain of nested scopes, the resolution process skips class definitions. This rule prevents odd interactions between class attributes and local variable access. If a name binding operation occurs in a class definition, it creates an attribute on the resulting class object. To access this variable in a method, or in a function nested within a method, an attribute reference must be used, either via self or via the class name.

An alternative would have been to allow name binding in class scope to behave exactly like name binding in function scope. This rule would allow class attributes to be referenced either via attribute reference or simple name. This option was ruled out because it would have been inconsistent with all other forms of class and instance attribute access, which always use attribute references. Code that used simple names would have been obscure.

That said, even if it was possible, this kind of definition looks really obscure and probably can be refactored into something simpler.

Edit: if you really, really want your class hierarchy look like this, you can just "monkey patch" A:

class A(object):
    class B(object):
        pass

class _C(object):
    class D(A.B): 
        pass

A.C = _C
Sign up to request clarification or add additional context in comments.

1 Comment

You're spot on about refactoring: B shouldn't be part of A. But I still wanted to know whether it was possible to write it. (I find it somewhat unsatisfying that it isn't.)

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.