1

Let's say I have the following parent and child classes:

class A(object):
    def __init__(self, *args, **kwargs):
        self.a = kwargs.get('a', 'default_A')
        self.b = kwargs.get('b', 'default_B')

class B(A):

    a = "override_A"

    def __init__(self, *args, **kwargs):
        super(B, self).__init__(**kwargs)

b = B()

print b.b  # this is "default_B", as expected
print b.a  # I expected this to be "override_A"

What am I doing wrong here? I've tried to understand how inheritance works via answers like this one but haven't found something that describes this specific requirement.

3
  • @jonrsharpe I just added the semantic print statements. If you run the exact code you'll quickly realize that the issue is not a printing error. Commented Jun 23, 2016 at 8:14
  • Yep, I've edited the question to hopefully make that clearer. You hadn't distinguished which outputs were expected and which weren't. Commented Jun 23, 2016 at 8:16
  • See also stackoverflow.com/q/16852860/3001761 Commented Jun 23, 2016 at 8:22

1 Answer 1

8

You're mixing class and instance variables. B.a is a class variable, which is shadowed by the instance variable set in A.__init__().

You could for example use dict.setdefault():

class B(A):

    def __init__(self, *args, **kwargs):
        # If the key 'a' exists, this'll be effectively no-operation.
        # If not, then 'a' is set to 'override_A'.
        kwargs.setdefault('a', 'override_A')
        super(B, self).__init__(**kwargs)
Sign up to request clarification or add additional context in comments.

1 Comment

Why the (ab) though? This is a perfectly fine use of setdefault().

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.