Почему `object .__ init__` не принимает аргументов

Почему нетobject.__init__ принимать*args, **kwargs в качестве аргументов? Насколько я вижу, это ломает некоторый простой код очень раздражающим способом без каких-либо преимуществ:

Скажем, мы хотим убедиться, что все__init__называются все родительские классы. Пока каждый init следует простому соглашению вызоваsuper().__init__ это гарантирует, что вся иерархия будет пройдена и будет выполнена ровно один раз (также без необходимости указывать родителя). Проблема возникает, когда мы передаем аргументы:

class Foo:
    def __init__(self, *args, **kwargs):
        print("foo-init")
        super().__init__(*args, **kwargs) # error if there are arguments!

class Bar:
    def __init__(self, *args, **kwargs):
        print("bar-init")
        super().__init__(*args, **kwargs)

class Baz(Bar, Foo):
    def __init__(self, *args, **kwargs):
        print("baz-init")
        super().__init__(*args, **kwargs)

b1 = Baz() # works
b2 = Baz("error")

Каковы причины этого и каков лучший обходной путь (! Он легко решаем в моем конкретном случае, но который зависит от дополнительных знаний об иерархии)? Лучшее, что я могу видеть, это проверить, является ли родитель объектом, и в этом случае не выдавать ему никаких аргументов ... ужасно ужасно.

 Voo27 июн. 2012 г., 22:51
@ sr2222 Ожидается ли его использование в произвольной иерархии наследования? Да. Наследование - это часто используемое решение (состав работает достаточно часто), и ситуации, в которых вы ожидаете «произвольно» иерархии наследования с MI еще более редки. Так что нет проблем для 99,9% всех классов, но дляobject как базовый класс каждого объекта? Да, я ожидаю, что справлюсь с этим.
 Voo27 июн. 2012 г., 22:48
@jadkik Для того, кто нарушает «СУХОЙ» и не обязательно, если я пишу миксин. Но да, во многих случаях существует простой обходной путь, и МИ в любом случае не является хорошей идеей. Так что да, меня больше интересуют причины этого, но если бы было хорошее общее решение, это все равно было бы интересно.
 jadkik9427 июн. 2012 г., 22:47
Обычно вы должны знать, кто является родителем, а не просто передавать произвольные аргументы.
 Silas Ray27 июн. 2012 г., 22:53
Поэтому теперь нам нужно пометить классы как «предназначенные для использования для наследования». или нет? Вы просто создаете сложность и добавляете специальное поведение в случае, если только разработчики не будут ленивыми при наследовании от класса.
 Silas Ray27 июн. 2012 г., 22:50
По этой логике, КАЖДОЙ__init__() метод в каждом классе, который кто-либо пишет в Python, должен быть*args а также**kwargsдаже если их просто выбросить. Что не имеет большого смысла. И еще труднее понять, что делать с именованными аргументами (нужно ли добавлять их кargs и / илиkwargs прежде чем передать их вверх по цепочке? Просто уронить их?) Это тоже ломает OO, так как тогда все параметры для__init__() из n-го подкласса в конечном итоге в__init__() родителя без какого-либо контроля.

Ответы на вопрос(2)

Ты можешь видетьhttp://bugs.python.org/issue1683368 для обсуждения. Обратите внимание, что кто-то там на самом делеasked для того, чтобы вызвать ошибку. Также смобсуждение Python-Dev.

В любом случае, ваш дизайн довольно странный. Почему вы пишете каждый класс, чтобы взять неуказанный*args а также**kwargs? В общем случае лучше, чтобы методы принимали аргументы, в которых они нуждаются. Принятие открытых аргументов для всего может привести к всевозможным ошибкам, если кто-то, например, неправильно наберет имя ключевого слова. Иногда это необходимо, но это не должно быть способом действий по умолчанию.

 Voo27 июн. 2012 г., 22:56
Я пишу миксин, поэтому обычно не знаю своего родителя. Теперь я мог простоnot Вызовите super из моего смешанного кода и ожидайте, что реальный объект явно вызовет родительский конструктор, но это кажется подверженным ошибкам и избыточным. Но спасибо за сообщение об ошибке, я его прочту :)
Решение Вопроса

Рэймонд Хеттингерсупер () считается супер есть некоторая информация о том, как справиться с этим. Он находится в разделе «Практические советы».

Ваш ответ на вопрос