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.

Community
  • 1
  • 1
YPCrumble
  • 26,610
  • 23
  • 107
  • 172
  • @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. – YPCrumble Jun 23 '16 at 08:14
  • Yep, I've edited the question to hopefully make that clearer. You hadn't distinguished which outputs were expected and which weren't. – jonrsharpe Jun 23 '16 at 08:16
  • See also http://stackoverflow.com/q/16852860/3001761 – jonrsharpe Jun 23 '16 at 08:22

1 Answers1

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)
Ilja Everilä
  • 50,538
  • 7
  • 126
  • 127