【问题标题】:Python Inheritence from constructorPython从构造函数继承
【发布时间】:2020-09-24 02:00:59
【问题描述】:

person.py

class Person:
   """---A class representing a person---"""
   # Person constructor
   def __init__(self,n,a): 
       self.full_name = n
       self.age = a
class Student(Person):
    # Student constructor   
    def __init__(self,n,a,s):
       Person.__init__(self,n,a)
       self.school = s

driver.py

from person import *
    a = Student("Alice", 19, "Univ")

它抛出TypeError: __init__() takes 3 positional arguments but 4 were given 我尝试将 Student 类更改为以下内容:

class Student(Person):
        # Student constructor   
        def __init__(self,n,a,s):
           super().__init__(n,a)
           self.school = s

错误依然存在。

为什么会这样?是否需要 super() 关键字才能添加新属性?

编辑:问题解决了。呈现这种奇怪行为的源代码中存在缩进问题,因此应该关闭问题。

【问题讨论】:

    标签: python inheritance parent-child subclass super


    【解决方案1】:

    这一行:

    Person.__init__(self,n,a)
    

    是问题所在。回想一下,方法会自动传递对其自身的引用,因此您只需传递第二个。

    这也有一个成熟的模式:

    class Person
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    class Student(Person):
        def __init__(self, school, *args):
            super().__init__(*args)
            self.school = school
    
    student = Student('Washington Elementary', "Johnny Go'gettem", 10)
    

    尽管请注意,只需在Student.__init__ 内的Person.__init__ 调用中删除对self 的引用就足够了。


    请注意,您可以使用几个在某些情况下变得非常有用的装饰器来覆盖默认方法行为。在这里都不适用,只是一点知识来逗你的大脑:

    def SomeClass:
        attr = "class-scoped"
    
        def __init__(self):
            self.attr = "instance-scoped"
    
        def some_method(self):
            return self.attr == "instance-scoped"
    
        @classmethod
        def some_classmethod(cls):
            return cls.attr == "class-scoped"
    
        @staticmethod
        def some_staticmethod():
            return "I'm not given a \"self\" parameter at all!"
    

    classmethods 作为替代构造函数特别有用

    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        @classmethod
        def from_tuple(cls, tup) -> "Person":
            """Expects a tuple of (name, age) and constructs a Person"""
            name, age = tup
            return cls(name, age)
    
        @classmethod
        def from_dict(cls, dct) -> "Person":
            """Expects a dictionary with keys "name" and "age" and constructs a Person"""
            try:
                name = dct['name']
                age = dct['age']
            except KeyError:
                raise ValueError(f"Dictionary {dct} does not have required keys 'name' and 'age'")
            else:
                return cls(name, age)
    

    【讨论】:

    • 我认为问题不在于构造函数本身......这是我编写的源代码中的一些错误缩进。我不小心为 cmets 添加了空格或制表符,这会导致逻辑上的不良行为。删除空格后一切正常。我只是无法专注于编写 Java 或 C 来弄清楚缩进或空格在 Python 中的重要性!
    • @Jerry213 缩进会改变行为,但是鉴于您发布的代码,您提到的错误消息是预期的,其缩进似乎是正确的。考虑 Python 中的空格相当于 Java/C 中的花括号——它会有所帮助:)
    猜你喜欢
    • 2013-06-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 2011-09-09
    相关资源
    最近更新 更多