В Python, скажем, у меня есть некоторый класс Circle, который наследуется от Shape. Форма нуждается в координатах x и y, и, кроме того, Circle нуждается в радиусе. Я хочу, чтобы иметь возможность инициализировать Circle, делая что-то вроде
c = Circle(x=1., y=5., r=3.)
Circle наследует от формы, поэтому мне нужно использовать именованные аргументы для __init__
, потому что разные классы требуют разных конструкторов. Я мог бы вручную установить x, y и r.
class Shape(object):
def __init__(self, **kwargs):
self.x = kwargs['x']
self.y = kwargs['y']
class Circle(Shape):
def __init__(self, **kwargs):
super(Circle, self).__init__(**kwargs)
self.r = kwargs['r']
или я мог бы автоматически установить атрибуты моего круга, используя self.__dict__.update(kwargs)
class Shape(object):
def __init__(self, **kwargs):
self.__dict__.update(**kwargs)
class Circle(Shape):
def __init__(self, **kwargs):
super(Circle, self).__init__(**kwargs)
Преимущество этого заключается в том, что меньше кода, и мне не нужно поддерживать шаблон, например self.foo = kwargs['foo']
. Недостатком является то, что не очевидно, какие аргументы необходимы для Circle. Это считается чит или это хороший стиль (до тех пор, пока интерфейс для Circle хорошо документирован)?
Спасибо, всем, за ваши продуманные ответы. Мне понравилось, когда я экспериментировал с организацией моего кода, но я убеждаюсь, что я заменил его корректным передачей аргументов и проверил четкую проверку ошибок в производственном коде.