В Python, скажем, у меня есть класс Circle, который наследуется от Shape. Shape нужны координаты x и y, и, кроме того, Circle нужен радиус. Я хочу иметь возможность инициализировать Circle, выполнив что-то вроде
c = Circle(x=1., y=5., r=3.)
Круг наследуется от фигуры, поэтому мне нужно использовать именованные аргументы для __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 хорошо документирован)?
Спасибо всем за ваши вдумчивые ответы. Хак self.__dict__.update(**kwargs)
был полезен для меня, когда я экспериментировал с организацией своего кода, но я позабочусь о том, чтобы заменить его на правильную передачу аргументов в явном виде и наглядную проверку ошибок в рабочем коде.