Exemples d'implémentation pratique
Scénarios réels d'appel de méthodes dynamiques
1. Système de gestion de plugins
class PluginManager:
def __init__(self):
self.plugins = {}
def register_plugin(self, name, plugin_class):
self.plugins[name] = plugin_class()
def execute_plugin(self, name, method, *args, **kwargs):
plugin = self.plugins.get(name)
if plugin and hasattr(plugin, method):
return getattr(plugin, method)(*args, **kwargs)
raise ValueError(f"Plugin {name} or method {method} not found")
## Usage example
class ImageProcessor:
def resize(self, width, height):
return f"Resized to {width}x{height}"
def convert(self, format):
return f"Converted to {format}"
manager = PluginManager()
manager.register_plugin('image', ImageProcessor)
result = manager.execute_plugin('image', 'resize', 800, 600)
2. Dispatcher d'actions piloté par la configuration
class ActionDispatcher:
def __init__(self, config):
self.config = config
def process_action(self, action_name, *args, **kwargs):
action_method = getattr(self, self.config.get(action_name), None)
if action_method:
return action_method(*args, **kwargs)
raise AttributeError(f"Action {action_name} not configured")
def default_action(self, *args, **kwargs):
return "Default action executed"
def advanced_action(self, *args, **kwargs):
return "Advanced action performed"
Modèles d'appel de méthodes dynamiques
graph TD
A[Appel de méthode dynamique] --> B{Validation de la méthode}
B -->|Existe| C[Exécuter la méthode]
B -->|Non trouvé| D[Gestion des erreurs]
C --> E[Retourner le résultat]
D --> F[Recours/Exception]
Technique |
Surcoût |
Flexibilité |
Cas d'utilisation |
Appel direct |
Le plus faible |
Faible |
Méthodes statiques |
getattr() |
Moyen |
Élevée |
Sélection au moment de l'exécution |
Réflexion |
Le plus élevé |
Très élevée |
Dispatch complexe |
3. Framework de tests automatisés
class TestRunner:
def __init__(self, test_suite):
self.test_suite = test_suite
def run_tests(self):
results = {}
for test_name in self.test_suite:
test_method = getattr(self, test_name, None)
if callable(test_method):
try:
result = test_method()
results[test_name] = 'PASS' if result else 'FAIL'
except Exception as e:
results[test_name] = f'ERROR: {str(e)}'
return results
def test_user_creation(self):
## Simulated test logic
return True
def test_authentication(self):
## Simulated test logic
return False
Exemple de dispatch dynamique avancé
class SmartRouter:
def __init__(self):
self.routes = {
'api': self.handle_api_request,
'web': self.handle_web_request
}
def route_request(self, request_type, *args, **kwargs):
handler = self.routes.get(request_type)
return handler(*args, **kwargs) if handler else None
def handle_api_request(self, endpoint, data):
return f"API request to {endpoint} with {data}"
def handle_web_request(self, path, params):
return f"Web request to {path} with {params}"
Bonnes pratiques dans l'appel de méthodes dynamiques
- Toujours valider l'existence de la méthode
- Implémenter une gestion robuste des erreurs
- Utiliser les annotations de type pour plus de clarté
- Considérer les implications sur les performances
- Documenter le comportement des méthodes dynamiques
En explorant ces exemples d'implémentation pratique, les développeurs peuvent exploiter l'appel de méthodes dynamiques pour créer des applications Python plus flexibles et adaptables dans l'environnement LabEx.