recherche

装饰器(decorator)是一种高级Python语法。装饰器可以对一个函数、方法或者类进行加工。在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果。相对于其它方式,装饰器语法简单,代码可读性高。因此,装饰器在Python项目中有广泛的应用。

前面快速介绍了装饰器的语法,在这里,我们将深入装饰器内部工作机制,更详细更系统地介绍装饰器的内容,并学习自己编写新的装饰器的更多高级语法。

什么是装饰器

装饰是为函数和类指定管理代码的一种方式。Python装饰器以两种形式呈现:

【1】函数装饰器在函数定义的时候进行名称重绑定,提供一个逻辑层来管理函数和方法或随后对它们的调用。

【2】类装饰器在类定义的时候进行名称重绑定,提供一个逻辑层来管理类,或管理随后调用它们所创建的实例。

简而言之,装饰器提供了一种方法,在函数和类定义语句的末尾插入自动运行的代码——对于函数装饰器,在def的末尾;对于类装饰器,在class的末尾。这样的代码可以扮演不同的角色。
装饰器提供了一些和代码维护性和审美相关的有点。此外,作为结构化工具,装饰器自然地促进了代码封装,这减少了冗余性并使得未来变得更容易。

函数装饰器

通过在一个函数的def语句的末尾运行另一个函数,把最初的函数名重新绑定到结果。

用法

装饰器在紧挨着定义一个函数或方法的def语句之前的一行编写,并且它由@符号以及紧随其后的对于元函数的一个引用组成——这是管理另一个函数的一个函数(或其他可调用对象)。
在编码上,函数装饰器自动将如下语法:

@decorator 
def F(arg): 
... 
F(99)

映射为这个对等形式:

def F(arg): 
... 
F = decorator(F) 
F(99)

这里的装饰器是一个单参数的可调用对象,它返回与F具有相同数目的参数的一个可调用对象。
当随后调用F函数的时候,它自动调用装饰器所返回的对象。

换句话说,装饰实际把如下的第一行映射为第二行(尽管装饰器只在装饰的时候运行一次)

fun(6,7) 
decorator(func)(6,7) 

这一自动名称重绑定也解释了之前介绍的静态方法和property装饰器语法的原因:

class C: 
@staticmethod 
def meth(...):... 
@property 
def name(self):...

实现

装饰器自身是返回可调用对象的可调用对象。实际上,它可以是任意类型的可调用对象,并且返回任意类型的可调用对象:函数和类的任何组合都可以使用,尽管一些组合更适合于特定的背景。

有一种常用的编码模式——装饰器返回了一个包装器,包装器把最初的函数保持到一个封闭的作用域中:

def decorator(F): 
def wrapper(*args): 
# 使用 F 和 *args 
# 调用原来的F(*args) 
return wrapper 
@decorator 
def func(x,y): 
... 
func(6,7)

当随后调用名称func的时候,它确实调用装饰器所返回的包装器函数;随后包装器函数可能运行最初的func,因为它在一个封闭的作用域中仍然可以使用。

为了对类做同样的事情,我们可以重载调用操作:

class decorator: 
def __init__(self,func): 
self.func = func 
def __call__(self,*args): 
# 使用self.func和args 
# self.func(*args)调用最初的func 
@decorator 
def func(x,y): 
... 
func(6,7)

但是,要注意的是,基于类的代码中,它对于拦截简单函数有效,但当它应用于类方法函数时,并不很有效:
如下反例:

class decorator: 
def __init__(self,func): 
self.func = func 
def __call__(self,*args): 
# 调用self.func(*args)失败,因为C实例参数无法传递 
class C: 
@decorator 
def method(self,x,y): 
...

这时候装饰的方法重绑定到一个类的方法上,而不是一个简单的函数,这一点带来的问题是,当装饰器的方法__call__随后运行的时候,其中的self接受装饰器类实例,并且类C的实例不会包含到一个*args中。

这时候,嵌套函数的替代方法工作得更好:

def decorator: 
def warpper(*args): 
# ... 
return wrapper 
@decorator 
def func(x,y): 
... 
func(6,7) 
class C: 
@decorator 
def method(self,x,y): 
... 
x = C() 
x.method(6,7)

类装饰器

类装饰器与函数装饰器使用相同的语法和非常相似的编码方式。类装饰器是管理类的一种方式,或者用管理或扩展类所创建的实例的额外逻辑,来包装实例构建调用。

用法

假设类装饰器返回一个可调用对象的一个单参数的函数,类装饰器的语法为:

@decorator 
class C: 
... 
x = C(99)

等同于下面的语法:

class C: 
... 
C = decorator(C) 
x = C(99)

直接效果是随后调用类名会创建一个实例,该实例会触发装饰器所返回的可调用对象,而不是调用最初的类自身。

实现

类装饰器返回的可调用对象,通常创建并返回最初的类的一个新的实例,以某种方式来扩展对其接口的管理。例如,下面的实例插入一个对象来拦截一个类实例的未定义的属性:

def decorator(cls): 
class Wrapper: 
def __init__(self,*args): 
self.wrapped = cls(*args) 
def __getattr__(self,name): 
return getattr(self.wrapped,name) 
return Wrapper 
@decorator 
class C: # C = decorator(C) 
def __init__(self,x,y): # Run by Wrapper.__init__ 
self.attr = 'spam' 
x = C(6,7) # 等价于Wrapper(6,7) 
print(x.attr)

在这个例子中,装饰器把类的名称重新绑定到另一个类,这个类在一个封闭的作用域中保持了最初的类。

就像函数装饰器一样,类装饰器通常可以编写为一个创建并返回可调用对象的“工厂”函数。

装饰器嵌套

有时候,一个装饰器不够,装饰器语法允许我们向一个装饰器的函数或方法添加包装器逻辑的多个层。这种形式的装饰器的语法为:

@A 
@B 
@C 
def f(...): 
...

如下这样转换:

def f(...): 
... 
f = A(B(C(f))) 

这里,最初的函数通过3个不同的装饰器传递,每个装饰器处理前一个结果。

装饰器参数

函数装饰器和类装饰器都能接受参数,如下:

@decorator(A,B) 
def F(arg): 
... 
F(99)

自动映射到其对等形式:

def F(arg): 
... 
F = decorator(A,B)(F) 
F(99)

装饰器参数在装饰之前就解析了,并且它们通常用来保持状态信息供随后的调用使用。例如,这个例子中的装饰器函数,可能采用如下形式:

def decorator(A,B): 
# 保存或使用A和B 
def actualDecorator(F): 
# 保存或使用函数 F 
# 返回一个可调用对象 
return callable 
return actualDecorator

以上,这是装饰器的基础知识,接下来将学习编写自己的装饰器。

Déclaration
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Comment utiliser Python pour trouver la distribution ZIPF d'un fichier texteComment utiliser Python pour trouver la distribution ZIPF d'un fichier texteMar 05, 2025 am 09:58 AM

Ce tutoriel montre comment utiliser Python pour traiter le concept statistique de la loi de Zipf et démontre l'efficacité de la lecture et du tri de Python de gros fichiers texte lors du traitement de la loi. Vous vous demandez peut-être ce que signifie le terme distribution ZIPF. Pour comprendre ce terme, nous devons d'abord définir la loi de Zipf. Ne vous inquiétez pas, je vais essayer de simplifier les instructions. La loi de Zipf La loi de Zipf signifie simplement: dans un grand corpus en langage naturel, les mots les plus fréquents apparaissent environ deux fois plus fréquemment que les deuxième mots fréquents, trois fois comme les troisième mots fréquents, quatre fois comme quatrième mots fréquents, etc. Regardons un exemple. Si vous regardez le corpus brun en anglais américain, vous remarquerez que le mot le plus fréquent est "th

Comment utiliser la belle soupe pour analyser HTML?Comment utiliser la belle soupe pour analyser HTML?Mar 10, 2025 pm 06:54 PM

Cet article explique comment utiliser la belle soupe, une bibliothèque Python, pour analyser HTML. Il détaille des méthodes courantes comme find (), find_all (), select () et get_text () pour l'extraction des données, la gestion de diverses structures et erreurs HTML et alternatives (Sel

Filtrage d'image en pythonFiltrage d'image en pythonMar 03, 2025 am 09:44 AM

Traiter avec des images bruyantes est un problème courant, en particulier avec des photos de téléphones portables ou de caméras basse résolution. Ce tutoriel explore les techniques de filtrage d'images dans Python à l'aide d'OpenCV pour résoudre ce problème. Filtrage d'image: un outil puissant Filtre d'image

Comment travailler avec des documents PDF à l'aide de PythonComment travailler avec des documents PDF à l'aide de PythonMar 02, 2025 am 09:54 AM

Les fichiers PDF sont populaires pour leur compatibilité multiplateforme, avec du contenu et de la mise en page cohérents sur les systèmes d'exploitation, les appareils de lecture et les logiciels. Cependant, contrairement aux fichiers de texte brut de traitement Python, les fichiers PDF sont des fichiers binaires avec des structures plus complexes et contiennent des éléments tels que des polices, des couleurs et des images. Heureusement, il n'est pas difficile de traiter les fichiers PDF avec les modules externes de Python. Cet article utilisera le module PYPDF2 pour montrer comment ouvrir un fichier PDF, imprimer une page et extraire du texte. Pour la création et l'édition des fichiers PDF, veuillez vous référer à un autre tutoriel de moi. Préparation Le noyau réside dans l'utilisation du module externe PYPDF2. Tout d'abord, l'installez en utilisant PIP: pip is p

Comment se cacher en utilisant Redis dans les applications DjangoComment se cacher en utilisant Redis dans les applications DjangoMar 02, 2025 am 10:10 AM

Ce tutoriel montre comment tirer parti de la mise en cache Redis pour augmenter les performances des applications Python, en particulier dans un cadre Django. Nous couvrirons l'installation redis, la configuration de Django et les comparaisons de performances pour mettre en évidence le bien

Comment effectuer l'apprentissage en profondeur avec TensorFlow ou Pytorch?Comment effectuer l'apprentissage en profondeur avec TensorFlow ou Pytorch?Mar 10, 2025 pm 06:52 PM

Cet article compare TensorFlow et Pytorch pour l'apprentissage en profondeur. Il détaille les étapes impliquées: préparation des données, construction de modèles, formation, évaluation et déploiement. Différences clés entre les cadres, en particulier en ce qui concerne le raisin informatique

Introduction à la programmation parallèle et simultanée dans PythonIntroduction à la programmation parallèle et simultanée dans PythonMar 03, 2025 am 10:32 AM

Python, un favori pour la science et le traitement des données, propose un écosystème riche pour l'informatique haute performance. Cependant, la programmation parallèle dans Python présente des défis uniques. Ce tutoriel explore ces défis, en se concentrant sur l'interprète mondial

Comment implémenter votre propre structure de données dans PythonComment implémenter votre propre structure de données dans PythonMar 03, 2025 am 09:28 AM

Ce didacticiel montre la création d'une structure de données de pipeline personnalisée dans Python 3, en tirant parti des classes et de la surcharge de l'opérateur pour une fonctionnalité améliorée. La flexibilité du pipeline réside dans sa capacité à appliquer une série de fonctions à un ensemble de données, GE

See all articles

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semainesBy尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
4 Il y a quelques semainesBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
4 Il y a quelques semainesBy尊渡假赌尊渡假赌尊渡假赌

Outils chauds

DVWA

DVWA

Damn Vulnerable Web App (DVWA) est une application Web PHP/MySQL très vulnérable. Ses principaux objectifs sont d'aider les professionnels de la sécurité à tester leurs compétences et leurs outils dans un environnement juridique, d'aider les développeurs Web à mieux comprendre le processus de sécurisation des applications Web et d'aider les enseignants/étudiants à enseigner/apprendre dans un environnement de classe. Application Web sécurité. L'objectif de DVWA est de mettre en pratique certaines des vulnérabilités Web les plus courantes via une interface simple et directe, avec différents degrés de difficulté. Veuillez noter que ce logiciel

PhpStorm version Mac

PhpStorm version Mac

Le dernier (2018.2.1) outil de développement intégré PHP professionnel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

MinGW - GNU minimaliste pour Windows

MinGW - GNU minimaliste pour Windows

Ce projet est en cours de migration vers osdn.net/projects/mingw, vous pouvez continuer à nous suivre là-bas. MinGW : un port Windows natif de GNU Compiler Collection (GCC), des bibliothèques d'importation et des fichiers d'en-tête librement distribuables pour la création d'applications Windows natives ; inclut des extensions du runtime MSVC pour prendre en charge la fonctionnalité C99. Tous les logiciels MinGW peuvent fonctionner sur les plates-formes Windows 64 bits.

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Puissant environnement de développement intégré PHP