web-dev-qa-db-fra.com

Python: Différence entre kwargs.pop () et kwargs.get ()

J'ai vu les deux manières mais je ne comprends pas quelle est la différence et ce que je devrais utiliser comme "meilleure pratique"

def custom_function(**kwargs):
    foo = kwargs.pop('foo')
    bar = kwargs.pop('bar')
    ...

def custom_function2(**kwargs):
    foo = kwargs.get('foo')
    bar = kwargs.get('bar')
    ...
10
Aliquis

get (key [ default]) : retourne la valeur de key si key est dans le dictionnaire, sinon default. Si default n'est pas spécifié, la valeur par défaut est None, de sorte que cette méthode ne déclenche jamais une KeyError.

d = {'a' :1, 'c' :2}
print(d.get('b', 0)) # return 0
print(d.get('c', 0)) # return 2

pop (clé [ défaut]) si la clé est dans le dictionnaire, supprimez-le et renvoyez sa valeur, sinon renvoyez la valeur par défaut. Si default n'est pas indiqué et que la clé ne figure pas dans le dictionnaire, une variable KeyError est générée.

d = {'a' :1, 'c' :2}
print(d.pop('c', 0)) # return 2
print(d) # returns {'a': 1}
print(d.get('c', 0)) # return 0

NB: En ce qui concerne la question des meilleures pratiques, je dirais que cela dépend de votre cas d'utilisation mais que je choisirais par défaut .get sauf si j'ai réellement besoin de .pop

9
DhiaTN

La différence est pop supprime également l'élément du dict.

Il n'y a pas de meilleure pratique. Utilisez celui qui convient le mieux à votre cas d'utilisation particulier.

La plupart du temps, tout ce dont vous avez besoin est getting.

D'autres fois, vous voulez vous assurer qu'aucun kwarg supplémentaire/inattendu n'est fourni. Dans ce cas, il est commode d'utiliser pop. Par exemple.:

a = kw.pop('a')
b = kw.pop('b')
if kw:
    raise TypeError('Unepxected kwargs provided: %s' % list(kw.keys()))
5
shx2

Donc, les fonctions get et pop font des choses très différentes

get est utilisé pour renvoyer une valeur pour une clé donnée dans le dictionnaire

pop supprime la valeur du dictionnaire et renvoie la valeur supprimée

Toutes les fonctions du dictionnaire sont documentées ici (pour python3): https://docs.python.org/3/library/stdtypes.html#mapping-types-dict

2
hwhite4

Prenons l'exemple suivant, où l'utilisation de get ou pop fait une différence:

Commençons par get:

class Foo(object):
    def __init__(self, foo_param=None):
        print("In Foo: {}".format(foo_param))

class Bar(Foo):
    def __init__(self, **kwargs):
        bar_param = kwargs.get('bar_param')
        print("In Bar: {}".format(bar_param))
        super(Bar, self).__init__(**kwargs)

bar = Bar(foo_param='F', bar_param='B')

Cet extrait de code déclenche une exception TypeError:

TypeError: __init__() got an unexpected keyword argument 'bar_param'

Lorsque Bar exécute super(Bar, self).__init__(**kwargs), il transmet à Foo le même message qu’il a reçu: {foo_param='F', bar_param='B'}. Ensuite, Foo soulève TypeError car les paramètres d’entrée ne respectent pas son interface.

Si vous popbar_param avant d'exécuter l'appel à super, Foo ne reçoit que le paramètre d'entrée requis foo_param, et tout va bien.

class Foo(object):
    def __init__(self, foo_param=None):
        print("In Foo: {}".format(foo_param))

class Bar(Foo):
    def __init__(self, **kwargs):
        bar_param = kwargs.pop('bar_param')
        print("In Bar: {}".format(bar_param))
        super(Bar, self).__init__(**kwargs)

bar = Bar(foo_param='F', bar_param='B')

La sortie est:

In Bar: B
In Foo: F
1
ssoler