[Python] Élimine le branchement conditionnel par if en utilisant pleinement Enum et eval

Déclencheur

J'ai été impressionné par la lecture de M. Masuda Comment écrire la «classification des cas». Tout a commencé par essais et erreurs, en se demandant si cela pouvait être fait avec Python. J'avais l'intention de le garder dans mes propres notes, mais je pensais que peut-être certaines personnes pourraient avoir des problèmes similaires, J'ai décidé de poster.

Lors de l'utilisation si

À titre d'exemple, considérons le code pour trouver l'aire d'une figure.

def calculate_area(shape_type, shape_info):
    if shape_type == 'triangle':
        return shape_info['bottom'] * shape_info['height'] / 2

    if shape_type == 'rectangle':
        return shape_info['bottom'] * shape_info['height']

Je ne suis pas content que le nombre d'instructions if dans la fonction augmente à mesure que les types de chiffres augmentent. (Ceci est un exemple simple, mais il sera difficile à corriger s'il est imbriqué)

Préparer la classe

Préparons une classe pour chaque figure comme préparation préliminaire.

from abc import ABCMeta, abstractmethod

class Shape(metaclass=ABCMeta):
    def __init__(self, shape_info):
        self.shape_info = shape_info

    @abstractmethod
    def calculate_area(self):
        pass

class Triangle(Shape):
    def calculate_area(self):
        return self.shape_info['bottom'] * self.shape_info['height'] / 2

class Rectangle(Shape):
    def calculate_area(self):
        return self.shape_info['bottom'] * self.shape_info['height']

Nous avons préparé la classe Triangle et la classe Rectangle. Cependant, si c'est tout, quelle classe est instanciée avec if pour chaque shape_type lors de l'appel Il semble qu'il sera nécessaire de séparer les cas.

if shape_type == 'triangle':
    shape = Triangle(shape_info)

if shape_type == 'rectangle':
    shape = Rectangle(shape_info)

Utiliser Enum et eval

En utilisant Enum, shape_type et nom de classe peuvent être liés, Avec eval, vous pouvez exécuter le contenu d'une chaîne tel quel en tant que syntaxe Python.

class ShapeType(Enum):
    triangle = 'Triangle'
    rectangle = 'Rectangle'

    @classmethod
    def get_shape_instance(cls, shape_type, shape_info):
        return eval(cls[shape_type].value)(shape_info)
shape = ShapeType.get_shape_instance(shape_type, shape_info)

Il peut y avoir des lacunes dans le texte, mais pardonnez-moi. J'espère que cet article aide quelqu'un.

Recommended Posts

[Python] Élimine le branchement conditionnel par if en utilisant pleinement Enum et eval
Branchement conditionnel de Python appris avec la chimioinfomatique
[Introduction to Data Scientists] Bases de Python ♬ Branchements conditionnels et boucles
Extraction de tweet.js (json.loads et eval) (Python)
Je veux faire revivre la légendaire combinaison Nintendo en utilisant pleinement l'IA et la technologie RH!
Compréhension complète du threading Python et du multitraitement
environnement de développement python -utilisation de pyenv et virtualenv-
Python> Trier par nombre et trier par alphabet> Utiliser trié ()
Traitement asynchrone de Python ~ Comprenez parfaitement async et attendez ~
Paiza Python Primer 2: Apprenez les opérateurs de branchement conditionnel et de comparaison
Module [Python of Hikari-] Chapitre 08-03 (Importation et utilisation de la bibliothèque standard)
Application de Python: Nettoyage des données Partie 3: Utilisation d'OpenCV et prétraitement des données d'image
[Python] Résumé de l'utilisation des fonctions de fractionnement et de jointure
Comparaison de l'utilisation des fonctions d'ordre supérieur dans Python 2 et 3
[Python of Hikari-] Chapitre 05-07 Syntaxe de contrôle (branchement conditionnel de la notation d'inclusion)
Le processus de création et d'amélioration du code Python orienté objet
[Vous devez le savoir! ] J'ai essayé de mettre en place un environnement Python de manière rentable en utilisant pleinement les privilèges des étudiants universitaires.