Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Decorateur sur un appel de fonction

+1 vote

En python, on ne peut décorer une fonction qu'à la définition de celle-ci, pourquoi ne pas avoir étendu aux appels de fonction ?

L'idée typiquement serait de pouvoir décorer une fonction d'une lib externe et donc d'éviter d'avoir à la wrapper en changeant son nom

Un exemple concret avec la librairie requests, on veut vérifier à chaque appel des fonctions get et post que la connection internet est toujours ok et donc on écrit un code qui ressemblerait à ça:

def check_connection(func):
    def wrapper(*args, **kwargs):
        try:
            func(*args, **kwargs)
        except ConnectionError:
            print('No internet.')
            sys.exit(0)


    return wrapper


@check_connection
html = requests.get('https://google.fr')

[....]

@check_connection
requests.post('http://httpbin.org/post', data = {'key':'value'})

Je me retrouve souvent dans un cas de figure où cette fonctionnalité me manque et donc je me pose la question, y a t-il une méthode Pythonique déjà existante qui m'aurait échappé ?

Sinon, pensez-vous que cette idée est interessante et mérite d'ếtre débattue sur python-ideas ?

demandé 23-Sep par superlevure (120 points)

1 Réponse

+2 votes
 
Meilleure réponse

oui, c'est possible.

Sans modifier ton code d'exemple :

html = check_connection(requests.get)('https://google.fr')
check_connection(requests.post)('http://httpbin.org/post', data = {'key':'value'})

Par ailleurs, dans le cas de ton exemple, on peut aller voir vers un context manager pour pour écrire:

with check_connection():
    html = requests.get('https://google.fr')

with check_connection():
    requests.post('http://httpbin.org/post', data = {'key':'value'})

une possiblité d'implémentation étant:

from contextlib import contextmanager

@contexmanager
def check_connection():
    try:
        yield
    except ConnectionError:
        print('No internet.')
        sys.exit(0)
répondu 24-Sep par bubulle (2,208 points)
sélectionné 24-Sep par superlevure
...