23

In the following code class B has inherited yay attribute from class A, I expected this. I'd also expect that inner class B.Foo behaves the same way but it doesn't.

How to make B.Foo to inherit alice attribute from class A? I need that the inner subclass Foo in B has both the attributes alice and bob.

Thanks.

>>> class A:
...     yay = True
...     class Foo:
...             alice = True
...
>>> class B(A):
...     nay = False
...     class Foo:
...             bob = False
>>> B.yay
True
>>> B.Foo.alice
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: class Foo has no attribute 'alice'
2
  • 3
    Why do you think you need inner classes? I've never seen a single situation where they would have occured to me as solution. Also, what's wrong with explicitly inheriting (as in class Foo(A.Foo))? Commented Apr 7, 2011 at 21:07
  • 2
    You can always write equivalent solution without inner classes, but sometimes express code structure and class relations very well. Imagine a collection and an iterator - classical example of inner class usage (though more C++ oriented). Commented Apr 7, 2011 at 21:18

3 Answers 3

20

The reason why B.Foo.alice gave you an error is because there's no connection between Foo attribute of class A and Foo attribute of class B.

In B, attribute Foo has a class object value that completely replaces class object value inherited from A.

This should fix it:

class B(A):
    nay = False
    class Foo(A.Foo):
        bob = False

In general, it helps, at least for me, to think of a class body contents as a sequence of attributes with certain assigned values.

In case of class B, we have:

  1. yay attribute that has value True inherited from A.
  2. nay attribute that has value False.
  3. Foo attribute that has class object.

Class methods are also attributes that have callable objects as values.

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

Comments

9

Inheritance is a per-class thing. In your code class B inherits from class A, but just because both of them have inner class Foo doesn't tell us anything about their inheritance.

If you want B.Foo to have the attributes from A.Foo, you need to make B.Foo inherit from A.Foo:

class B(A):
    class Foo(A.Foo):
        bob = False

3 Comments

In fact, Python's last Zen Koan specifically says "Namespaces are one honking great idea -- let's do more of those!". B.Foo is then obviously different from A.Foo.
In Python 3, class Foo: pass is the correct syntax for new style (the only style) classes it has. See: docs.python.org/release/3.0.1/reference/…
@pavel You're right. So since the OP didn't say which version is using I will remove section about classes.
1

Foo is it's own class. It does not inherit from A. Because of this, it does not have any fields of A. The fact that is nested in a subclass of A does not change anything.

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.