Python继承更改子类字段

huangapple go评论63阅读模式
英文:

Python inheritance changing child class field

问题

我正在创建一个带有继承的类形式的数据库。我希望子类继承父类的所有字段,但实际上并没有发生,因为我收到了"AttributeError: 'Child'对象没有属性'default'"。如果我在Child类中定义'default'变量,那么它可以工作,但我希望Child类继承父类的'default'值,而不是在Child类中重新定义它。如果我不指定Child类中的__init__方法,那么所有字段都会被继承,但我无法更改它们的值。

#!/usr/bin/env python3
import sys

class Parent():
    def __init__(self, y, x):
        self.result = self.action(x, y)
        self.default = 5  # 这里需要将'default'设置为self.default
    def action(self, x, y):
        return (x * y)
    def setResult(self, x):
        def __init__(self, y, x):
            self.result = x

class Child(Parent):

    def __init__(self, y, x):
        super().__init__(y, x)  # 调用父类的初始化方法
    def action(self, x, y):
        return (x / y)

def main(argv):
    data = Child(2, 3)
    print(data.result)
    print(data.default)

if __name__ == "__main__":
    main(sys.argv[1:])

注意:在Parent类的构造函数中,我已经将default设置为self.default,并且在Child类的构造函数中使用super().__init__(y, x)来调用父类的构造函数。

英文:

I am creating a database in a for of classes with inheritance. I would like Child class to inherit all field of parent class, however it doesn't happen as I am getting "AttributeError: 'Child' object has no attribute 'default'". If I define 'default' variable in Child class, I will get it working, but I want that Child inherited parent value for 'default' and not redefine it again at Child class. If I don't specify __init__ method in Child class, all fields are inherited, but I can't change their value.

#!/usr/bin/env python3
import sys

class Parent():
    def __init__(self, y, x):
        self.result = self.action(x,y)
        default = 5
    def action(self,x,y):
        return (x*y)
    def setResult(self, x):
        def __init__(self, y, x):
            self.result = x
class Child(Parent):

    def __init__(self, y, x):
        self.result = self.action(x,y)
    def action(self,x,y):
        return (x/y)


def main(argv):
    data = Child(2,3)
    print (data.result)
    print (data.default)

if __name__ == "__main__":
    main(sys.argv[1:])

答案1

得分: 1

以下是要翻译的代码部分:

class Parent():
    def __init__(self, y, x):
        self.result = self.action(x,y)
        self.default = 5 #----- this requires a "self" to attach to any instance of the class
class Child(Parent):
    def __init__(self, y, x):
        super().__init__(y, x)
        self.result = self.action(x,y)

关于已经在评论中阐述的内容的重申:

你正在通过创建一个函数来覆盖 __init__

__init__ 是一个内置函数,如果你不自己创建一个,Python 会使用它自己创建的。__init__ 在类被初始化时总是被运行。

当你在这个函数中将变量声明为 self 时,你正在将这些变量添加到创建的类的任何实例中(而不是在其他函数中使用 self)。

通过编写自己的版本 __init__,你需要确保它创建了类应该具有的每个值 - 对于那些想要使用继承的情况,这就是我们有 super() 函数的原因。

super() 函数用于访问父类或同级类的方法和属性。

通过调用 super().__init__(y, x),你调用了 Parent()__init__ 函数,从而 '继承' 了它的值/设置/属性。

为了更加明确这个主题 - 以下两个类(实际上)是相同的:

class Child(Parent):
    def __init__(self, y, x):
        super().__init__(y, x)
    def action(self,x,y):
        return (x/y)
class Child(Parent):
    def action(self,x,y):
        return (x/y)

进一步参考:
https://www.w3schools.com/python/gloss_python_class_init.asp
https://www.w3schools.com/python/ref_func_super.asp

英文:

To consolidate the comments you received into an actual answer:

class Parent():
    def __init__(self, y, x):
        self.result = self.action(x,y)
        self.default = 5 #----- this requires a "self" to attach to any instance of the class
class Child(Parent):
    def __init__(self, y, x):
        super().__init__(y, x)
        self.result = self.action(x,y)

To restate everything that has been stated in the comments:

You are overriding __init__ by making a function for it.

__init__ is a built-in function, if you don't make one yourself - python uses one it makes itself. __init__ is always run when a class is being initiated.

When you declare variables to self in this function, you are adding the variables to any instance of the class that is created. (as opposed to using self in some other function)

By writing your own version of __init__ you are taking on the burden of making sure that it creates every value the class is supposed to have - for cases where you want to make use of inheritance, this is why we have the super() function.

The super() function is used to give access to methods and properties of a parent or sibling class.

By calling super().__init__(y, x) you call Parent()'s __init__ function and thus 'inherit' its values / settings / properties.

Just to crystallize the subject more - the following two classes are (effectively) identical:

class Child(Parent):
    def __init__(self, y, x):
        super().__init__(y, x)
    def action(self,x,y):
        return (x/y)
class Child(Parent):
    def action(self,x,y):
        return (x/y)

Further reference:<br>
https://www.w3schools.com/python/gloss_python_class_init.asp <br>
https://www.w3schools.com/python/ref_func_super.asp

huangapple
  • 本文由 发表于 2023年2月6日 06:58:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75356091.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定