2
votes

Lever une exception dans python dict.get ()

en fait, je sais déjà que ce que je veux faire est un peu étrange, mais je pense que cela ira bien dans mon code, alors je demande:

y a-t-il un moyen de faire quelque chose comme ça: p>

foo = { 'a':1, 'b':2, 'c':3 }
bar = { 'd':4, 'f':5, 'g':6 }

foo.get('h', bar.get('h'))

lever une exception au lieu de None , au cas où dict.get () 'échouerait'?

foo. get ('h', bar.get ('h', rise)) augmentera SyntaxError

foo.get ('h', bar .get ('h', Exception)) renverra simplement Exception

pour l'instant je travaille juste avec sinon foo.get ( 'h', bar.get ('h')): lever l'exception mais s'il y a un moyen de lever directement dans le dict.get () je serais très heureux.

Merci


4 commentaires

vous pouvez simplement sous-classer dict et faire en sorte que get fasse exactement ce que vous voulez


N'utilisez pas get () car il piège l'IndexError pour vous. Si vous voulez réellement l'indexError, utilisez simplement foo ['h']


Les réponses "utilisez simplement des crochets" sont correctes, mais voici une explication pour expliquer pourquoi: stackoverflow.com/a/11041421/769971 Aussi, je vous promets que plus tard, la fonction .get () vous sera utile. Vous devriez également apprendre à l'utiliser.


exactement, je sais pourquoi .get () est utilisé, je voulais juste lever une exception lorsque la clé n'est pas trouvée au lieu de None , sans avoir à utiliser des conditions


5 Réponses :


0
votes

Vous pouvez faire:

class MyException(Exception):
    pass


try:
    value = dict['h']
except KeyError:
    raise MyException('my message')


0 commentaires

8
votes

En utilisant des indices, voici le comportement par défaut:

try:
    d['unknown key']
except KeyError as e:
    raise CustomException('Custom message') from e

Si vous souhaitez ensuite lever une exception personnalisée, vous pouvez le faire:

try:
    d['unknown key']
except KeyError:
    raise CustomException('Custom message')

Et pour inclure le stacktrace de KeyError:

d={}
d['unknown key'] --> Raises a KeyError


1 commentaires

Merci. Je sais déjà à ce sujet, je voulais utiliser .get () pour ne pas avoir à utiliser de conditions mais à la fin, on dirait que je vais devoir le faire de toute façon



0
votes

Vous pouvez créer une classe personnalisée pour votre dict avec la fonction magique:

class GetAndRaise:
    def __init__(self):
        self.dict = dict()
    def __getitem__(self, key):
        try:
            return self.dict[key]
        except ValueError:
            raise MyException
    def __setitem__(self, key, value):
        self.dict[key] = value
    def get(self, key):
        return self[key]


1 commentaires

Je ne peux pas tolérer cela ... ne faites pas cela s'il vous plaît, car la fonctionnalité qu'il recherche est déjà dans la classe dict.



1
votes

puisque vous avez déjà de bonnes réponses, je vais vous donner la réponse du gâchis comme une chose ... d'apprentissage.

foo = MyDict({ 'a':1, 'b':2, 'c':3 })
bar = MyDict({ 'd':4, 'f':5, 'g':6 })
foo.get('h', bar.get('h', error="Exception")) #  returns a syntaxerror object
foo.get('h', bar.get('h', error="raise"))  # raises a syntax error

maintenant vous pouvez faire:

class MyDict(dict):
    def get(self, key, default=None, error=None):
        res = super().get(key,default)
        if res is None:
            if error == 'raise':
                raise SyntaxError()
            elif error == 'Exception':
                return SyntaxError()
        return res

super () vous permet d'accéder aux membres de votre superclasse afin vous pouvez avoir votre propre get tout en utilisant les parents get en interne


2 commentaires

" je vais vous donner la réponse au gâchis " Il semble que vous ayez de la concurrence. 😃


@TrebuchetMS quand j'ai commencé à écrire ceci, il n'y avait pas beaucoup de réponses folles



0
votes

Vous pouvez utiliser le conteneur ChainMap , qui encapsule deux dictionnaires en un seul:

from collections import ChainMap

foo = { 'a':1, 'b':2, 'c':3 }
bar = { 'd':4, 'f':5, 'g':6 }

ChainMap(foo, bar)['h']


2 commentaires

désolé peut-être une question stupide - comment cela soulève-t-il l'exception nécessaire au lieu de simplement récupérer la valeur ailleurs?


@VincentBuscarello Vous obtenez l'exception KeyError si la valeur h n'est pas dans le dict chaîné.