7
votes

Comment puis-je faire une sécurité par défaut pour des clients indexprimants?

Plusieurs fois (même plusieurs dans une rangée), j'ai été mordu par le bug de dist par défaut: oublier que quelque chose est en réalité une différend de défaut et le traite comme un dictionnaire régulier.

d = defaultdict(list)

...

try:
  v = d["key"]
except KeyError:
  print "Sorry, no dice!"


0 commentaires

5 Réponses :


7
votes

Utilisez différent idiom: xxx


4 commentaires

Cela demande la permission, cependant.


+1 Je pense que le test avec dans est beaucoup meilleur style que à l'exception de KeyError , non seulement pour defaultDicts.


Je voudrais accepter, mais utiliser dans signifie que vous vous retrouvez avec deux recherches de dictionnaire, une pour la vérification de la clé et une pour la récupération réelle des données. De plus, le chèque est de plus en plus élaboré les plus niveaux de nidification. v = d [k1] [k2] [k3] vs. code> si k1 en d: \ `tmp1 = d [k1]` \ `Si K2 dans TMP1:" \ `tmp2 = tmp1 [k2] \` \ `Si K3 dans TMP2:` etcetera. En outre, avoir des clients qui souhaitent seulement lire de D de l'accord sur les détails de la mise en œuvre, comme si D est un dict par défaut ou non ne semble pas très attrayant pour moi.


@bp - Je pourrais avoir tort, mais ne dans fait tenter et attraper l'exception dans les coulisses?



14
votes

Vous pouvez toujours le convertir en une dicte normale.

d = collections.defaultdict(list)
d = dict(d)


0 commentaires

5
votes

Vous pouvez empêcher la création de valeurs par défaut en attribuant un d.default_factory = Aucun . Cependant, je n'aime pas vraiment l'idée d'un objet changeait soudainement le comportement. Je préférerais copier les valeurs au nouveau dict à moins d'imposer une pénalité de performance grave.


2 commentaires

Merci beaucoup pour me mettre sur la bonne voie avec cela. Je n'ai pas de problèmes particuliers à modifier le comportement de ce type d'objet parce que je pense que vérifier si un objet prend en charge un protocole particulier est beaucoup mieux que de vérifier son type. Dans ce cas, cheching si elle prend en charge le protocole de mappage est bien meilleure que de vérifier de manière défensive si un dictionnaire pourrait potentiellement être un contrat de diffusion et de modifier le comportement du client en conséquence.


Qu'entendez-vous par «N'aimez pas tout à fait l'idée d'un objet changeait soudainement le comportement»? Si je dis d = dict (d) au lieu de d.default_factory = Aucun , sauf si je passe autour de la référence à l'ancien d c'est fonctionnel équivalent et ne force pas à créer un nouveau dictionnaire. Tant que le code suivant ne tente pas de restaurer l'usine (sonne fou) c'est un canard.



2
votes

C'est exactement le comportement que vous souhaitez à partir d'un defaultDict et non un bug . Si vous ne le voulez pas, n'utilisez pas de par défaut.

Si vous continuez à oublier quelles variables de type ont, alors nommez-les de manière appropriée - par exemple suffixer vos noms de diffusion par défaut avec "_dict".


1 commentaires

J'espérais que je pouvais oublier cette torsion hongroise en utilisant python :-) Je préférerais nommer un canard potentiel s'il s'agit de charbons que de propager un nom de nom de code si je décide à un point de tourner D Spinise par exemple ...



1
votes

Utilisation de l'idée de RKHAYROV de réinitialisation self.default_factory , voici une sous-classe à commande de defaultDict : xxx

par exemple: xxx


0 commentaires