Пробираясь через класс Counter python в collections, я обнаружил, что мне показалось странным: они явно не используют аргумент self аргументах функции __init__.
См. Код ниже (скопировано напрямую без строки документации):
class Counter(dict):
def __init__(*args, **kwds):
if not args:
raise TypeError("descriptor '__init__' of 'Counter' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 argments, got %d' % len(args))
super(Counter, self).__init__()
self.update(*args, **kwds)
Позже в этом же классе методы update и subtract также определяются таким же образом.
Прежде чем указать мне на вопросы о том, как self работает в классах, отмечу, что я не считаю, что это дубликат вопрос. Я понимаю, как обычно работает self и что self не является ключевым словом (просто стандартная практика) и т.д. Я также понимаю, что этот код работает (я не подвергаю сомнению правильность синтаксиса * unpack/explode/starred-expressions)
Мой вопрос больше связан с тем, почему...
- Зачем реализовывать
__init__и другие нормальные (non-@static/@classметоды) такого класса и при каких обстоятельствах я должен рассмотреть возможность использования этого в будущем? - Почему только определенные методы в одном классе реализованы таким образом?
- При каких обстоятельствах эти методы будут вызываться без аргументов (если они есть), инициирующих первую ошибку TypeError?
- В каких условиях эти методы можно назвать с
selfзаполненной вручную (например,Counter.__init__(some_counter))? Или другие примеры?
Я должен думать, что это как-то связано с TypeError ("дескриптор...").