En Python, créez un décorateur qui accepte dynamiquement les arguments Créer un décorateur

Contexte

Si vous définissez et utilisez votre propre décorateur en Python, vous souhaiterez peut-être pouvoir transmettre des arguments au décorateur plus tard.

Emplacement d'utilisation d'origine du décorateur


@my_decorator
def hoge():
	# ...

Si vous implémentez un décorateur général, si vous voulez pouvoir passer des arguments au décorateur plus tard, Il faudra réécrire tous les décorateurs qui ont été utilisés comme ↑ comme ↓.

Lors de la définition d'arguments lors de l'utilisation d'un décorateur


@my_decorator(arg1='value1')
def hoge():
	# ...

Même si vous n'avez besoin d'aucun argument, vous devez mettre des parenthèses si l'implémentation du décorateur change.

Lorsqu'aucun argument n'est défini lors de l'utilisation du décorateur


@my_decorator()
def hoge():
	# ...

La réécriture de toutes les parties qui utilisent le décorateur est difficile à modifier et à vérifier, j'ai donc voulu le faire fonctionner sans parenthèses si aucun argument n'est nécessaire.

Objectif

Je veux créer un décorateur (my_decorator) qui peut utiliser dynamiquement des arguments comme indiqué ci-dessous. En passant, je voudrais l'implémenter en tant que décorateur pour les décorateurs afin que ces fonctions puissent être utilisées universellement.

python


#Sans arguments
@my_decorator
def hoge():
	pass

#Avec argument
@my_decorator(arg1='value1')
def fuga():
	pass

la mise en oeuvre

Implémentez un décorateur qui interprète dynamiquement les arguments à appliquer au décorateur, comme indiqué ci-dessous.

decorators.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import functools


def dynamic_args(func0):
    def wrapper(*args, **kwargs):
        if len(args) != 0 and callable(args[0]):
            #Lorsqu'une fonction est passée comme premier argument:Traitez comme un décorateur sans arguments
            func = args[0]
            return functools.wraps(func)(func0(func))
        else:
            #Autre:Traiter comme un décorateur avec des arguments
            def _wrapper(func):
                return functools.wraps(func)(func0(func, *args, **kwargs))
            return _wrapper
    return wrapper

Image d'utilisation

Si vous préparez un décorateur comme celui ci-dessus, vous pouvez atteindre votre objectif simplement en définissant votre propre décorateur comme suit.

python


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from decorators import dynamic_args


#Appliquez le décorateur créé ci-dessus à votre propre décorateur
@dynamic_args
def my_decorator(func, arg1='default_value1', arg2='default_value2'):
    def wrapper(*args, **kwargs):
    	#Arguments définis(arg1, arg2)Écrivez le processus que vous voulez réellement faire en utilisant
    	# ...
    return wrapper

Exemple d'utilisation

Comme exemple, créez un décorateur avec des parenthèses avant et après la valeur de retour (chaîne de caractères) avec le nom mon_décorateur.

sample.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from decorators import dynamic_args


#####################
#Définition propre du décorateur#
#####################
@dynamic_args
def my_decorator(func, before='「', after='」'):
    def wrapper(*args, **kwargs):
        return "{} {} {}".format(before, func(*args, **kwargs), after)
    return wrapper


##########################
#Exemple d'utilisation du décorateur sans argument#
##########################
@my_decorator
def func_without_args():
    return "Décorateur sans argument"

print(func_without_args()) # output:"Décorateur sans arguments"


##########################
#Exemple d'utilisation d'un décorateur avec des arguments#
##########################
@my_decorator(before='『', after='』')
def func_with_args():
    return "Décorateur avec arguments"

print(func_with_args()) # output:"Décorateur avec arguments"


####################################
#Exemple d'application d'un décorateur à une fonction prédéfinie#
####################################
def func_without_decorator():
    return "Pas de décorateur"


print(my_decorator(func_without_decorator)()) # output:"Pas de décorateur"
print(my_decorator(before="『", after="』")(func_without_decorator)()) # output:"Pas de décorateur"

référence

Astuces Python: Je veux passer des arguments au décorateur - Life with Python http://www.lifewithpython.com/2016/09/python-decorator-with-arguments.html

Expression de décorateur Python (2) -Quand un décorateur a un argument et que vous appliquez plusieurs décorateurs | Oubliez immédiatement le cerveau Une note pour cela http://jutememo.blogspot.jp/2008/10/python-2.html

python - AttributeError: 'str' object has no attribute 'module' - Stack Overflow http://stackoverflow.com/questions/18493879/attributeerror-str-object-has-no-attribute-module

Recommended Posts

En Python, créez un décorateur qui accepte dynamiquement les arguments Créer un décorateur
Créer une fonction en Python
Créer un dictionnaire en Python
Créer une fausse classe qui triche également est une instance
En Python, créez un décorateur qui accepte dynamiquement les arguments Créer un décorateur
Créer un conteneur DI avec Python
Créer un fichier binaire en Python
Créer un framework de décorateur à usage général pour Python
Créer une chaîne aléatoire en Python
Donner à un décorateur Python un alias qui passe un argument fixe
Créons un script qui s'enregistre avec Ideone.com en Python.
Créez le code qui renvoie "A et prétendant B" en python
[Python / Django] Créer une API Web qui répond au format JSON
[Python] Créez un LineBot qui s'exécute régulièrement
[GPS] Créer un fichier kml avec Python
Créons une base de données clients où le code QR est automatiquement émis en Python
Créez un environnement de test Vim + Python en 1 minute
Créer un fichier GIF en utilisant Pillow en Python
Je veux créer une fenêtre avec Python
Créer un graphique de distribution normale standard en Python
Comment créer un fichier JSON en Python
Créer un environnement virtuel avec conda avec Python
Créer une page qui se charge indéfiniment avec python
Créer un modèle d'investissement dynamique simple en Python
Python: créer une classe qui prend en charge l'affectation décompressée
Créer une nouvelle page en confluence avec Python
Créer un objet datetime à partir d'une chaîne en Python (Python 3.3)
Créer un package contenant des commandes globales en Python
Créez un fichier MIDI en Python en utilisant pretty_midi
Créer un modèle d'antenne cadre en Python dans KiCad
[Docker] Créez un environnement jupyterLab (python) en 3 minutes!
Créer Spatia Lite en Python
Créer un environnement Python
J'ai essayé de créer une classe qui peut facilement sérialiser Json en Python
Créez un plugin qui vous permet de rechercher les onglets Sublime Text 3 en Python
Je souhaite créer une file d'attente prioritaire pouvant être mise à jour avec Python (2.7)
Créer un bot de collecte de données en Python à l'aide de Selenium
[API LINE Messaging] Créez un menu riche avec Python
Créer un plugin pour exécuter Python Doctest sur Vim (2)
Créez un plug-in pour exécuter Python Doctest avec Vim (1)
Que contient cette variable (lorsque le script Python est en cours d'exécution)
Créez un faux serveur Minecraft en Python avec Quarry
MALSS (introduction), un outil qui prend en charge l'apprentissage automatique en Python
Prendre une capture d'écran en Python
Créer un plugin Wox (Python)
Importer dynamiquement des scripts en Python
Créer un bookmarklet en Python
Créer un tableau numpy python
Appeler dynamiquement des méthodes en Python
Dessinez un cœur en Python
Créer un répertoire avec python
Un programme polyvalent qui formate les chaînes de commande Linux avec python
Créer une portée locale en Python sans polluer l'espace de noms
Une fonction qui divise l'itérable en N morceaux en Python
Publication d'une bibliothèque qui masque les données de caractères dans les images Python
Boucle sur un générateur qui renvoie un itérateur de date en Python
[Python] Créez un linebot qui dessine n'importe quelle date sur une photo
Créer un compte enfant de connect with Stripe en Python