4

If I had a parent class attribute that all of the child classes are going to inherit, can I set a default so that when the object is created, it automatically take the default from the parent class and no argument has to be given when creating it?

class F1(object):
   def __init__(self, sick="flu"):
       self.sick = sick

class F2(F1):
   def __init__(self, sick, cure):
       super(F2, self).__init__(sick)
       self.cure = cure

a = F2("bed rest")
print(a.sick)
print(a.cure)

this is just a sample bit of code to show what I mean. I want every child to inherit the "sick" from the parent so I do not have to send that argument in when creating the object. Is this possible? Is there a different way of doing this same thing? Would it be better to make "sick" a class attribute?

5
  • 1
    Also, if the child WANTS to override the parent default, is that possible as well with what I am asking? Commented May 16, 2018 at 19:54
  • Was this question worded poorly or unclear? Commented May 17, 2018 at 12:40
  • I am guessing this question might not be answered... Commented May 22, 2018 at 0:37
  • 2
    what's that last comment supposed to do? scare away possible contributors?? Commented May 23, 2018 at 9:19
  • 2
    @netrate Your question did, indeed, get answered. Not only that: it even received two different answers. Could you please upvote/mark one of them as an accepted answer if you found them helpful? I know I did. Commented May 12, 2020 at 16:18

3 Answers 3

5

the problem with your code is, that you are declaring F2.__init__ to have two explicit arguments, even though you only want to pass one. If you want to be able to optionally override the creation argument of F1 you need to handle that yourself (see F3)

class F1(object):
   def __init__(self, sick="flu"):
       self.sick = sick

class F2(F1):
   def __init__(self, cure):
       super(F2, self).__init__()
       self.cure = cure

class F3(F1):
   def __init__(self, cure, sick=None):
       if sick is None:
          super(F3, self).__init__()
       else:
          super(F3, self).__init__(sick)
       self.cure = cure

a = F2("bed rest")
print("%s -> %s" % (a.sick, a.cure))

b = F3("inhale")
print("%s -> %s" % (b.sick, b.cure))

c = F3(sick="curiosity", cure="none")
print("%s -> %s" % (c.sick, c.cure))
Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly what I was looking for. I though about the same solution but assumed there was a simpler way of doing it. Thanks!
3

I know this is 5 years old, but I came across it trying to figure out a related issue and saw it has 4k views. Just thought I'd suggest an alternative:

class F1(object):
   def __init__(self, sick="flu"):
       self.sick = sick

class F2(F1):
   def __init__(self, cure="bed rest", **kwargs):
       super().__init__(**kwargs)
       self.cure = cure

a = F2(cure="wait it out")
print(a.sick)   # => flu
print(a.cure)   # => wait it out

a = F2(sick="covid", cure="quarantine")
print(a.sick)  # => covid
print(a.cure)  # => quarantine

a = F2(sick="anything")
print(a.sick)  # => anything
print(a.cure)  # => bed rest

(Of course, above works without declaring default value for cure as well.)

You could also do it without calling with requiring keyword arguments like so:

class F1(object):
   def __init__(self, sick="flu"):
       self.sick = sick

class F2(F1):
   # Without keyword arguments, must call args in order F2(cure, sick)
   def __init__(self, cure="bed rest", *args, **kwargs):
       super().__init__(*args, **kwargs)
       self.cure = cure

a = F2("sleep")
print(a.sick)   # => flu
print(a.cure)   # => sleep

a = F2(sick="covid", cure="quarantine")
print(a.sick)  # => covid
print(a.cure)  # => quarantine

a = F2("sleep", "any sickness")
print(a.sick)  # => any sickness
print(a.cure)  # => sleep

Comments

1

Using super is the standard way of doing this in Python. If you want to override, just override...

class F2(F1):
   def __init__(self, sick, cure):
       super(F2, self).__init__(sick)
       self.cure = cure
       self.sick = sick + 1

Adding class attribute could be an option, depending on your need. From your description, I'd say it sounds better, because the default value of sick never change, and that's probably what you need.

Using class attribute does not affect overriding, because when assigning attribute on an instance, class attribute is not touched. An example:

>>> class F:
...     a = 1
...
>>> f1, f2 = F(), F()
>>> f2.a = 2
>>> f1.a
1

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.