2017-09-20 5 views
2

Je suivais un tutoriel en ligne et le code est ceci:Dériver une liste python

class Hands(list): 
    def __init__(self, size=0, die_class=None, *args, **kwargs): 
     if not die_class: 
      raise ValueError("You must provide a die class") 
     super().__init__() 

     for _ in range(size): 
      self.append(die_class()) 

Il essentiellement des modèles un joueur avec un certain nombre de dés (size) et ce dés qu'ils détiennent (die_class).

Ma confusion est pourquoi avons-nous besoin d'appeler super().__init__? J'ai essayé d'exécuter le code sans cela et ça a bien fonctionné! Pourquoi l'appel est-il nécessaire?

+1

même si cela fonctionne maintenant car 'list' ne semble pas avoir besoin d'un constructeur par défaut, que se passe-t-il si les prochaines versions de python nécessitent que' __init__' soit appelé sur un objet 'list'? pourquoi _not_ appelant '__init__'? –

+0

Ce n'est pas nécessaire (mais c'est une bonne pratique), voir https://softwareengineering.stackexchange.com/questions/318165/is-calling-the-superclass-constructor-in-a-subclass-really-important –

+0

Je pense que ça casse Principe de Liskov. ça marche, d'accord, mais quand cela va-t-il se briser? –

Répondre

-1

super() vous permet d'éviter de vous référer explicitement à la classe de base. Plus important encore, avec l'héritage multiple, vous pouvez faire des choses comme this. À la fin de la journée, ce n'est pas nécessaire, c'est juste une bonne pratique.

+1

Je pense que vous manquez le point. –

1

Vous devez appeler __init__() si la classe de base est sûre qu'un code d'initialisation est exécuté. Qu'il semble fonctionner sans cet appel peut être une coïncidence, ou vous n'avez peut-être tout simplement pas encore rencontré le problème. Même s'il fonctionne régulièrement dans la version et l'implémentation Python que vous utilisez actuellement, il n'est pas garanti que les autres versions et implémentations fonctionnent sans appeler la méthode __init__ de la classe de base.

Aussi, vous pouvez réellement utiliser qui appellent pour remplir la liste avec vos objets de dés:

class Hands(list): 
    def __init__(self, size=0, die_factory=None): 
     if not die_factory: 
      raise ValueError('You must provide a die factory') 
     super().__init__(die_factory() for _ in range(size)) 

J'ai retitré die_class-die_factory comme tout appelable qui produit un nouvel objet de la matrice peut être utilisé ici.

Note: Vous pouvez violez la est-une relation entreHands et list ici, sauf si un objet Hands est en fait un list, à savoir toutes méthodes et le comportement des listes font également sens pour Hands objets.