Не могу разобраться до конца в классах Python. Задаю объекты:
p1 = Point(50,70) # объект класса Point, задающий начальную координату
c1 = Color(10,15,10) # задает цвет
r1 = Rectangle(p1,40,70,c1) #в нем и загвоздка, а точнее в p1 и c1
Как сделать так, чтобы r1 имел также аргументы x и y и r,g,b, которые имеют p1 и c1 соответственно.
!!! в моем классе Rectangle self.pointIn = pointIn и self.color = color явно заданы неправильно
class Point(object):
def __init__(self,x=0, y=0):
self.x = x
self.y = y
def modify_point(self, x1,y1):
self.x = x1
self.y = y1
def to_tuple(self):
return (self.x, self.y)
class Color(object):
def __init__(self,r=0, g=0, b=0):
self.r = r
self.g = g
self.b = b
def to_tuple(self):
return (self.r, self.g, self.b)
class Rectangle(Point, Color):
def __init__(self, pointIn, width, hight, color):
self.width = width
self.hight = hight
self.pointIn = pointIn
self.color = color
Ответ
Прямоугольник может иметь цвет. Прямоугольник сам по себе цветом не является. То есть логичнее использовать: rectangle.color.r вместо rectangle.r и не наследовать от Color (тем более вы уже используете композицию: self.color определён).
Как сделать так, чтобы r1 имел также аргументы x и y и r,g,b, которые имеют p1 и c1 соответственно.
Если забыть, что это прямоугольники, точки, цвета и рассматривать задачу как упражнение по использованию множественного наследования (которое следует избегать, если вы не знаете точно зачем оно вам нужно в конкретном случае), то чтобы правильно проинициализировать унаследованные атрибуты базовых классов, необходимо вызывать super().__init__(**kwargs)
#!/usr/bin/env python3
class A:
def __init__(self, a, **kwargs):
super().__init__(**kwargs)
self.a = a
def __repr__(self):
keys = sorted(self.__dict__)
items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
return "{}({})".format(type(self).__name__, ", ".join(items))
class B:
def __init__(self, b, **kwargs):
super().__init__(**kwargs)
self.b = b
class C(A, B):
def __init__(self, c, **kwargs):
super().__init__(**kwargs)
self.c = c
print(C(a=1, b=2, c=3))
super().__init__() вызов только один в C.__init__(), не смотря на то что C имеет два базовых класса.
A.__init__() и B.__init__() существуют и также вызывают super().__init__() и все эти методы имеют совместимые аргументы (за счёт **kwargs). См. Python’s super() considered super!
__repr__ метод (с реализацией из документации types.SimpleNamespace) определён, чтобы напечатать C объект. Вывод показывает, что все атрибуты правильно установлены.
Ключевое понятие здесь—порядок разрешения методов (MRO)—порядок, в котором вызываются методы базовых классов:
>>> [klass.__name__ for klass in C.mro()]
['C', 'A', 'B', 'object']
С.__init__ ожидаемо вызывает родительский A.__init__ (через super().__init__()). A класс не наследует от B, но A.__init__ вызывает (через super().__init__()) B.__init__ согласно MRO, который вызывает object.__init__ и цепочка заканчивается.
object встречается в этом списке только один раз, хотя он является базовым классом как для A так и B классов (то есть C наследует от object класса дважды). Чтобы вычислить порядок вызовов, в Питоне используется C3-линеаризация суперкласса
Комментариев нет:
Отправить комментарий