【问题标题】:How to modify/override inherited class function in python?如何在python中修改/覆盖继承的类函数?
【发布时间】:2019-06-19 15:44:54
【问题描述】:

我在父类和继承类中都有确切的函数名称say_hello。我想在 Kitten 类中指定参数name,但允许用户在 Cat 类中指定参数。

有没有办法避免在 Kitten 类的 say_hello 函数中重复 return ('Hello '+name) 行?

目前:

class Cat:
    def __init__(self):
        pass

    def say_hello(name):
        return ('Hello '+name)

class Kitten(Cat):
    def __init__(self):
        super().__init__()

    def say_hello(name='Thomas'):
        return ('Hello '+name)

x = Cat
print (x.say_hello("Sally"))
y = Kitten
print (y.say_hello())

理想情况下:

class Cat:
    def __init__(self):
        pass

    def say_hello(name):
        return ('Hello '+name)

class Kitten(Cat):
    def __init__(self):
        super().__init__()

    def say_hello():
        return super().say_hello(name='Thomas') # Something like this, so this portion of the code doesn't need to repeat completely

【问题讨论】:

  • 我只是想这可以使用return Cat.say_hello(name='Thomas') 来完成。这是做我想做的事情的正确方法吗?

标签: python-3.x class inheritance overriding


【解决方案1】:

say_hello 方法应包含self 作为第一个参数,以便它可以使用super() 函数访问父级的say_hello 方法。您还应该通过用括号调用它来实例化一个类:

class Cat:
    def say_hello(self, name):
        return 'Hello ' + name

class Kitten(Cat):
    def say_hello(self, name='Thomas'):
        return super().say_hello(name)

x = Cat()
print(x.say_hello("Sally"))
y = Kitten()
print(y.say_hello())

这个输出:

Hello Sally
Hello Thomas

【讨论】:

  • 我试图了解潜在的不良做法。如果我在小猫的say_helloreturn Cat.say_hello(name='Thomas') 中不包括self。这是一个不好的做法?即使我不需要使用super() 功能?
  • 实例方法的第一个参数始终是实例对象本身,即使您将其命名为 self 以外的名称。如果该方法不需要访问任何实例属性,则可以避免将self 作为第一个参数,而是使用@staticmethod 装饰器使其成为静态方法。
  • 如果name 在其他参数之间怎么办,比如say_hello(self, a, b, name, c, d="d", e="e")
【解决方案2】:

我认为您可能会错过有关课程的一点,这对您想要实现的目标至关重要。

让我们首先定义一个类Cat,但仔细看看与你的区别。

class Cat:
    def __init__(self, name):
        self.name = name

    def say_hello(self):
        return self.name

现在看看魔法,我稍后再解释:

cat = Cat("Sally")
print(cat.say_hello())
>>> "Sally"

与您的代码相比发生了什么?

首先,您的__init__ 方法不带参数。我的版本是name。此外,我将其分配给实例变量 self.name 。 有了这个分配,我可以访问每个方法中实例化时提供的名称,其中 self 作为它的第一个参数。什么是实例化? 好吧,在您的代码中,您调用了x = Cat。有了这个 x 是类的对象,而不是实例。你需要实例化你的类。

通过在我的代码cat = Cat("Sally") 中这样做,python 所做的是调用该类的 __init__ 方法并返回它的一个实例,并按照 __init__ 方法中的指定设置/完成。

在我的例子中,我设置了self.name = name,在示例中,self.name 的值设置为“Sally”。

所以每当我在一个方法中调用self.name 时,它的参数中包含self,它在实例化后变成“Sally”。

现在Cat 的类应该很清楚了。

现在该怎么办?

简单地从这个类继承!

见:

class Cat:
    def __init__(self, name):
        self.name = name

    def say_hello(self):
        return self.name


class Kitten(Cat):
    def __init__(self, name):
        # This is done for convenience
        super().__init__(name)

有了这个 Kitten-,与 Cat-一样,实例有一个名字,并继承了 say_hello() 方法来说出它的名字。

我希望这会有所帮助。

【讨论】:

  • 这个示例代码简化了我试图构建的更大/复杂的代码。我明白你为什么根据我的例子提出这个建议,猫的名字应该被视为一个属性,但我的重点实际上是关于函数及其在父类和继承类中重叠的参数,猫和名字只是占位符说明我正在努力工作的地方。不过谢谢!
猜你喜欢
  • 2019-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
  • 2015-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多