2016-03-26 2 views
-1

EDIT: О, извините, ребята. Этот вопрос является дублирующим, но не дублированным связанным. Я нашел то, что мне нужно в этом вопросе, возможно, я должен попробовать больше ключевых слов для поиска в следующий раз. Subclassing dict: should dict.init() be called?Нужно ли использовать super() .__ init __() в этом случае?

В моем случае, я реализую update, __setitem__ в классе StrKeyDict(dict) и __new__ унаследовал от dict может создать пустую dict для обеспечения update может работать, я не думаю, что нужно использовать super().__init__() снова.

Код из Fluent Python example-code/attic/dicts/strkeydict_dictsub.py

import collections.abc 

class StrKeyDict(dict): 

    def __init__(self, iterable=None, **kwds): 
     super().__init__() 
     self.update(iterable, **kwds) 

    def __missing__(self, key): 
     if isinstance(key, str): 
      raise KeyError(key) 
     return self[str(key)] 

    def __contains__(self, key): 
     return key in self.keys() or str(key) in self.keys() 

    def __setitem__(self, key, item): 
     super().__setitem__(str(key), item) 

    def get(self, key, default=None): 
     try: 
      return self[key] 
     except KeyError: 
      return default 

    def update(self, iterable=None, **kwds): 
     if iterable is not None: 
      if isinstance(iterable, collections.abc.Mapping): 
       pairs = iterable.items() 
      else: 
       pairs = ((k, v) for k, v in iterable) 
      for key, value in pairs: 
       self[key] = value 
     if kwds: 
      self.update(kwds) 

Когда мы используем

d = StrKeyDict(a=1,b=2) 

, например, для создания экземпляра д, реальное событие является:

1.Call __new__ который унаследован от суперкласса dict, чтобы создать пустой экземпляр dict

2.Call __init__ для инициализировать экземпляр

Так же, как я уже сказал, я реализую update, __setitem__ в классе StrKeyDict(dict). Так что здесь необходимо использовать super().__init__(). Спасибо!

+0

'super() .__ init __()' делает то же самое, что и в другом месте, он вызывает '__init __()' в суперклассе. –

+0

becasue i реализовать 'update',' __setitem__' в 'классе StrKeyDict (dict)' и '__new__', унаследованном от' dict', может создать пустой 'dict', чтобы гарантировать, что' update' может работать, я не думаю необходимо снова использовать 'super() .__ init __()'. –

+0

, если вы знаете лучше всех, почему вы даже задали этот вопрос? Особенно, если вы просто собираетесь спорить со всеми, вы не хотите ответа, вы хотите, чтобы вам сказали, что вы правы, вы нет. –

ответ

1

Суперкласс '__init__() может или не будет делать что-то необходимое для его инициализации. Если вы знаете, в чем дело, вы можете принять обоснованное решение. Если вы не знаете, что лучше всего называть его на всякий случай.

Теперь, если вы не вызываете его, потому что это необязательно, и реализация базового класса изменяется таким образом, который делает его необходимым, вам придется его исправить.

С другой стороны, есть несколько случаев, когда вызов суперкласса __init__() - плохая идея, например, если он делает тяжелые вычисления, очень специфичные для суперкласса и отличающиеся в подклассе.

FWIW мой подход всегда вызывает super().__init__(), если у меня нет оснований не называть его.

1

В общем необходимо. И часто это необходимо для того, чтобы быть первым вызовом в вашем init. Сначала он вызывает функцию init родительского класса (dict). Обычно он создает свою базовую структуру данных.

+0

Я думаю, что вы говорили о «создании своей базовой структуры данных», это главная цель «супер» () .__ init __() 'в этом случае. –

Смежные вопросы