#python #inheritance #parent-child #subclass #super
#python #наследование #родитель-потомок #подкласс #супер
Вопрос:
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()
Требуется ли ключевое слово для добавления новых атрибутов?
РЕДАКТИРОВАТЬ: проблема решена. В исходном коде была проблема с отступом, отображающая это странное поведение, поэтому вопрос следует закрыть.
Ответ №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)
хотя обратите внимание, что простого удаления вашей ссылки self
в Person.__init__
вызове внутри Student.__init__
было бы достаточно.
Обратите внимание, что вы можете переопределить поведение метода по умолчанию с помощью нескольких декораторов, которые становятся весьма полезными в определенных ситуациях. Здесь не применяется ни то, ни другое, а просто немного знаний, чтобы немного подразнить ваш мозг:
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!"
classmethod
s особенно полезны в качестве альтернативных конструкторов
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)
Комментарии:
1. Я понял, что проблема не в конструкторе itself….It это с некоторым плохим отступом от исходного кода, который я пишу. Я случайно добавляю пробелы или табуляции для комментариев, что приводит к плохому поведению в логике. После удаления пробелов все работает нормально. Я просто не мог сосредоточиться на написании Java или C, выясняя, как учитываются отступы или пробелы в Python!
2. отступ @Jerry213 изменит поведение, но упомянутое вами сообщение об ошибке ожидается, учитывая опубликованный вами код, отступ которого кажется правильным. Рассмотрите пробелы в Python, эквивалентные фигурным скобкам в Java / C — это поможет 🙂