[PYTHON] Utilisez get autant que possible pour les références de type dictionnaire

Deux façons de référencer un type de dictionnaire (Dict) en Python

Il existe deux façons de rechercher la valeur d'un objet de type dictionnaire en Python.

  1. Reportez-vous tel quel
  2. Utilisez la méthode get

~~ Il vaut mieux ne pas utiliser l'ancien, mais ~~ * Corrigé. Voir les commentaires * Il vaut mieux ne pas trop utiliser l'ancien, mais j'en expliquerai la raison.

1. Lorsque vous vous référez tel quel

Créez une classe simple pour l'illustration.

sample_class.py


class SampleDict1:

    def __init__(self, params: dict):
        self.name = params['name']
        self.age = params['age']
        self.sex = params['sex']

Il s'agit d'une méthode permettant de transmettre les informations à créer en tant qu'argument de type dictionnaire lors de la création d'une instance. Je pense que vous pouvez le faire lorsque vous stockez les données créées dans JSON dans le corps de la requête de l'API, que vous les convertissez en un type de dictionnaire côté serveur et que vous les transmettez à la couche de modèle.

Créons maintenant une instance de cette classe.

from sample_class import SampleDict1

params = {'name':'test',
          'age':38,
          'sex':'male'}
sample_dict1 = SampleDict1(params)
print(sample_dict1.__dict__)
# {'name': 'test', 'age': 38, 'sex': 'male'}

J'ai pu le créer en toute sécurité. Si l'objet de type dictionnaire passé lors de la création de l'instance ne manque pas de paramètres, il n'y a pas de problème. Regardons maintenant le cas où l'objet dictionnaire ne contient pas de sexe.

from sample_class import SampleDict1

params = {'name':'test',
          'age':38}
sample_dict1 = SampleDict1(params)
# KeyError: 'sex'

Si vous référencez directement un objet de type dictionnaire et que la clé spécifiée n'existe pas dans l'objet, une exception appelée KeyError se produira. Par conséquent, par exemple, lorsque le paramètre sexe n'est pas requis, la méthode de référence directe doit être mise en œuvre comme suit.

sample_class.py


class SampleDict1:

    def __init__(self, params: dict):
        self.name = params['name']
        self.age = params['age']
        if 'sex' in params.keys():
            self.sex = params['sex']

Ou

sample_class.py


class SampleDict1:

    def __init__(self, params: dict):
        try:
            self.name = params['name']
            self.age = params['age']
            self.sex = params['sex']
        except KeyError:
            pass

… Cette dernière approche est complètement ridicule, mais peut être trouvée dans des sources avec beaucoup de code écrit par des personnes non qualifiées. De cette manière, la méthode de référencement direct d'un objet de type dictionnaire peut nécessiter une validation et une gestion des exceptions inutiles.

2. Utilisez la méthode get

Alors, que se passe-t-il lorsque vous utilisez la méthode get pour rechercher la valeur d'un objet dictionnaire?

sample_class.py


class SampleDict2:

    def __init__(self, params):
        self.name = params.get('name')
        self.age = params.get('age')
        self.sex = params.get('sex')

Créons une instance.

from sample_class import SampleDict2

params = {'name':'test',
          'age':38,
          'sex':'male'}
sample_dict2 = SampleDict2(params)
print(sample_dict2.__dict__)
# {'name': 'test', 'age': 38, 'sex': 'male'}

S'il n'y a pas de pénurie dans les paramètres, il a été créé normalement comme dans le cas de 1. Et si vous n'avez pas assez de paramètres?

from sample_class import SampleDict1

params = {'name':'test',
          'age':38}
sample_dict1 = SampleDict1(params)
print(sample_dict2.__dict__)
# {'name': 'test', 'age': 38, 'sex': None}

De cette manière, None a été stocké sans KeyError. Dans ce cas, aucun traitement supplémentaire n'est requis, par exemple lorsque le paramètre sexe n'est pas requis. De plus, la lisibilité n'est pas altérée par l'absence de validation inutile et de gestion des exceptions.

De plus, même si vous voulez dire «inconnu» lorsque le paramètre sexe n'a aucune valeur, vous pouvez l'écrire plus clairement que dans le cas de 1. Premièrement, si vous voulez faire référence directement à 1, vous l'implémenterez comme suit.

sample_class.py


class SampleDict1:

    def __init__(self, params: dict):
        self.name = params['name']
        self.age = params['age']
        if 'sex' in params.keys():
            self.sex = params['sex']
        else:
            self.sex = 'unknown'

D'autre part, lorsque vous utilisez la méthode get de 2, elle peut être implémentée comme suit.

sample_class.py


class SampleDict2:

    def __init__(self, params):
        self.name = params.get('name')
        self.age = params.get('age')
        self.sex = params.get('sex', 'unknown')
        # dict.get(key[, default])
        # Return the value for key if key is in the dictionary, else default.

De cette façon, lors de la définition de la valeur par défaut, il est possible d'écrire sur une ligne lors de l'utilisation de la méthode get de 2 tout en utilisant 4 lignes lors de l'utilisation de la méthode de référence directe de 1.

en conclusion

Comme nous l'avons vu ci-dessus, il est plus pratique d'utiliser la méthode get de 2 que la méthode de référence directe de 1 lors du référencement de la valeur d'un objet de type dictionnaire. Donc, si vous écrivez du code qui est directement référencé, veuillez changer tout ce code pour obtenir la méthode immédiatement (de toute urgence).

Supplément

Concernant le dernier exemple, même dans le cas de 1, vous pouvez écrire comme suit, mais nous ne le recommandons pas. Une ligne devient plus longue et il est facile de violer la règle des moins de 80 lignes définie par PEP8, et si vous coupez une ligne avec \ pour l'éviter, elle sera terriblement illisible et maintenable. Je pense qu'il vaut toujours mieux le diviser en quatre lignes que de le faire.

sample_class.py


class SampleDict1:

    def __init__(self, params: dict):
        self.name = params['name']
        self.age = params['age']
        self.sex = params['sex'] if 'sex' in params.keys() else 'unknown'
            

Recommended Posts

Utilisez get autant que possible pour les références de type dictionnaire
Utilisez BMFont comme police pour pyglet
AtCoder: Python: Automatisez autant que possible les tests d'échantillons.
Utilisez Flask comme étape suivante dans SimpleHTTPServer
Utilisez des références faibles