2
class A:
    class B(A):
        pass

This does not work. Why? How do I make something that behaves the same way?

By same I mean:

  • The same __class__.__name__
  • The same __class__.__qualname__
  • A.B.__base__ is A
7
  • What error does it throw? If it's name A not defined, it's because the definition of A isn't done by the time B is beginning to get defined. Commented Jan 28, 2014 at 21:04
  • @TankorSmash: line 2: NameError: name 'A' is not defined. Commented Jan 28, 2014 at 21:06
  • 4
    Why would you want this? Nested classes are already mostly nonsensical in Python, but a nested class inheriting from the outer class is exotic (though legal) even in Java, C# and the like. Commented Jan 28, 2014 at 21:08
  • 1
    Sup dawg, I heard you like classes. Commented Jan 28, 2014 at 21:10
  • 4
    @HristoVenev: That still doesn't explain why you need B inside A. Commented Jan 28, 2014 at 21:15

3 Answers 3

8

No, not without workarounds. The first class doesn't even exist at the time its body (including the class B(A) part) is executed. You can define the two separtely though:

class A:
    pass

class B(A):
    pass

A.B = B
B.__name__ = ...
B.__qualname__ = ...

But honestly this doesn't look like the best design or API.

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

Comments

1

Evaluation happens "inside out". Class A is not created until after everything in its class body is done. So at the time B is defined, A does not yet exist.

Your only option would be to define class B with some other base class, then write a class decorator or metaclass on A that looks inside A for attributes that are classes with the specified "dummy" base, and recreates them with A as their base.

The real question is why you feel you need to do this.

Comments

0

Just because metaclasses are amusing:

class GoofyMeta(type):
    def __new__(cls, clsname, bases, dct):
        dct['__qualname__'] = bases[0].__qualname__
        return super(GoofyMeta, cls).__new__(cls, bases[0].__name__, bases, dct)

class A:
    pass

#using python 3 syntax here
class B(A,metaclass=GoofyMeta):
    pass

B.__name__
Out[24]: 'A'

B.__qualname__
Out[25]: 'A'

And B.__base__ is A by definition.

As for why you'd want this, I'm pretty mystified. It seems like you can just use inheritance/composition normally like the rest of us :-)

(I'll also note that I didn't address B somehow being an inner class of A. I extra plus one don't know what you're trying to do with that.)

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.