Python继承 - 父类中是否可以有默认值?

4
如果我有一个所有子类都将继承的父类属性,我是否可以设置默认值,以便在创建对象时,它自动从父类中获取默认值,并且在创建对象时不需要提供任何参数?
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)

这只是一个示例代码,展示我想要的效果。我希望每个子对象都能从父对象继承“sick”,这样在创建对象时就不必传递该参数。这种做法可行吗?还有其他方式实现相同的效果吗?将“sick”作为类属性是否更好?


1
另外,如果子类想要覆盖父类的默认设置,那么我所询问的是否也可以实现? - netrate
这个问题的措辞是否不当或者不清楚? - netrate
我猜这个问题可能不会被回答... - netrate
2
那最后的评论是想干嘛?吓走潜在的贡献者吗? - umläute
2
@netrate,你的问题确实得到了回答。不仅如此:它甚至获得了两个不同的答案。如果你发现这些答案有帮助,能否请你点赞/标记其中一个作为“已采纳的答案”?我知道我会这么做。 - pfabri
3个回答

4
您的代码问题在于,您声明F2.__init__需要两个明确的参数,尽管您只想传递一个参数。 如果您想要能够可选地覆盖F1的创建参数,则需要自行处理(参见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))

这正是我一直在寻找的。我曾考虑过同样的解决方案,但认为可能有更简单的方法。谢谢! - pfabri

1

在Python中,使用super是这样做的标准方式。如果您想要覆盖,只需覆盖...

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

根据您的需求,添加class属性可能是一个选择。从您的描述来看,我会说这听起来更好,因为sick的默认值从不改变,这可能是您需要的。

使用class属性不会影响覆盖,因为在实例上分配属性时,不会触及类属性。一个例子:

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

0

我知道这已经是5年前的事了,但我在尝试解决一个相关问题时发现它有4k次浏览量。只是想建议一个替代方案:

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

当然,不声明 cure 的默认值也可以正常工作。

你也可以这样做,而不需要调用时使用关键字参数:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接