Maison  >  Article  >  développement back-end  >  Explication détaillée de l'exemple de partage de code de surcharge de l'opérateur Python

Explication détaillée de l'exemple de partage de code de surcharge de l'opérateur Python

高洛峰
高洛峰original
2017-03-10 09:07:101298parcourir

Cet article présente principalement les informations pertinentes pour une explication détaillée de l'exemple de partage de code de surcharge d'opérateur Python. Les amis qui en ont besoin peuvent se référer à

Surcharge d'opérateur Python

Python. Le langage fournit Il a la fonction de surcharge d'opérateurs et améliore la flexibilité du langage, qui est quelque peu similaire mais quelque peu différent de C. Compte tenu de sa nature particulière, nous discuterons aujourd'hui de la surcharge des opérateurs Python.

Le langage Python lui-même fournit de nombreuses méthodes magiques, et sa surcharge d'opérateurs est obtenue en réécrivant ces méthodes magiques intégrées à Python. Ces méthodes magiques commencent et se terminent toutes par des traits de soulignement doubles, similaires à la forme de __X__. Python intercepte les opérateurs via cette méthode de dénomination spéciale pour réaliser une surcharge. Lorsque les opérations intégrées de Python sont appliquées à un objet de classe, Python recherche et appelle la méthode spécifiée dans l'objet pour terminer l'opération.

Les classes peuvent surcharger les opérations intégrées telles que l'addition et la soustraction, l'impression, les appels de fonction, l'indexation, etc. La surcharge d'opérateurs fait que nos objets se comportent de la même manière que les objets intégrés. Python appellera automatiquement une telle méthode lors de l'appel d'un opérateur. Par exemple, si une classe implémente la méthode __add__, cette méthode sera appelée lorsqu'un objet de la classe apparaîtra dans l'opérateur.

Méthodes courantes de surcharge des opérateurs


tr>__call__ tr> tr>

方法名

重载说明

运算符调用方式

__init__

构造函数

对象创建: X = Class(args)

__del__

析构函数

X对象收回

__add__/__sub__

加减运算

 X Y, X =Y/X-Y, X-=Y

__or__

运算符|

X|Y, X|=Y

_repr__/__str__

打印/转换

print(X)、repr(X)/str(X)

__call__

函数调用

X(*args, **kwargs)

__getattr__

属性引用

X.undefined

__setattr__

属性赋值

X.any=value

__delattr__

属性删除

del X.any

__getattribute__

属性获取

X.any

__getitem__

索引运算

X[key],X[i:j]

__setitem__

索引赋值

X[key],X[i:j]=sequence

__delitem__

索引和分片删除

del X[key],del X[i:j]

__len__

长度

len(X)

__bool__

布尔测试

bool(X)

__lt__, __gt__, 

__le__, __ge__, 

__eq__, __ne__

特定的比较

依次为Xee3d56296b359dd6e2fa348252a69563Y,X0c053491a77177952c95ffb33c7e0a8b=Y, 

X==Y,X!=Y 

注释:(lt: less than, gt: greater than, 

  le: less equal, ge: greater equal, 

  eq: equal, ne: not equal 

__radd__

右侧加法

other X

__iadd__

实地(增强的)加法

X =Y(or else __add__)

__iter__, __next__

迭代

I=iter(X), next()

__contains__

成员关系测试

item in X(X为任何可迭代对象)

__index__

整数值

hex(X), bin(X),  oct(X)

__enter__, __exit__

环境管理器

with obj as var:

__get__, __set__, 

__delete__

描述符属性

X.attr, X.attr=value, del X.attr

__new__

创建

在__init__之前创建对象

Nom de la méthode
Description de la surcharge Méthode d'appel de l'opérateur
__init__ Constructeur Création d'objet : X = Class(args)
__del__ Destructeur Objet X récupéré
__add__/__sub__ Opérations d'addition et de soustraction X Y , X =Y /X-Y, > X|Y, X|=Y
_repr__/__str__ td>Imprimer/Convertir imprimer(X), repr(X)/str(X)
Appel de fonction X(*args, **kwargs)
__getattr__ Référence de l'attribut X.undefined
__setattr__ Affectation d'attribut X.any =value
__delattr__ Suppression d'attribut del X .any
__getattribute__ Attribut obtenir X[clé], X[clé], X[i:j]=séquence
__delitem__ Suppression d'index et de fragments del X[clé], del X[i : j]
__len__ Longueur len(X)
__bool__ Test booléen bool(X)
__lt__, __gt__, __le__, __ge__, __eq__, __ne__ Les comparaisons spécifiques sont X632bf1420c84fd56a79a6bad534b1b35Y, Xde401a2783e2509434aa7d711403a242=Y, X==Y, !=Y Remarque : (lt : inférieur à, gt : supérieur à, le : moins égal, ge : supérieur égal, eq : égal, ne : pas égal )
__radd__ Ajout côté droit Autre ajout X = Y (ou bien __add__)
__iter__, __next__ td> Itération I=iter(X), next( )
__contient__ Test d'adhésion élément dans X (X est n'importe quel objet itérable)
__index__ Valeur entière hex(X), bin(X ), oct(X)
__enter__, __exit__ Gestionnaire d'environnement td> avec obj comme var :
__get__ , __set__, __delete__ Attribut de descripteur X.attr, X.attr=value, del X .attr
__new__ Créer Créez l'objet avant __init__

Ce qui suit est une introduction à l'utilisation des méthodes d'opérateur couramment utilisées.

Constructeur et destructeur : __init__ et __del__

Leur fonction principale est de créer et de recycler des objets. Lors de la création des instances, le constructeur __init__ est. appelé. Lorsque l'objet instance est récupéré, le destructeur __del__ est automatiquement exécuté.

>>> class Human(): 
...   def __init__(self, n): 
...     self.name = n 
...       print("__init__ ",self.name) 
...   def __del__(self): 
...     print("__del__") 
...  
>>> h = Human('Tim') 
__init__ Tim 
>>> h = 'a' 
__del__

Opérations d'addition et de soustraction : __add__ et __sub__

Surcharge de ces deux les méthodes peuvent ajouter des opérations d’opérateur + aux objets ordinaires. Le code suivant montre comment utiliser l'opérateur +-. Si vous supprimez la méthode __sub__ dans le code, puis appelez l'opérateur moins, une erreur se produira.

>>> class Computation(): 
...   def __init__(self,value): 
...     self.value = value 
...   def __add__(self,other): 
...     return self.value + other 
...   def __sub__(self,other): 
...     return self.value - other 
...  
>>> c = Computation(5) 
>>> c + 5 
10 
>>> c - 3 
2

Représentation sous forme de chaîne de l'objet : __repr__ et __str__

Ces deux les méthodes sont utilisées pour représenter l'expression sous forme de chaîne de l'objet : les méthodes print() et str() appelleront la méthode __str__, et les méthodes print(), str() et repr() appelleront la méthode __repr__. Comme le montre l'exemple ci-dessous, lorsque deux méthodes sont définies en même temps, Python donnera la priorité à la recherche et à l'appel de la méthode __str__.

>>> class Str(object): 
...   def __str__(self): 
...     return "__str__ called"   
...   def __repr__(self): 
...     return "__repr__ called" 
...  
>>> s = Str() 
>>> print(s) 
__str__ called 
>>> repr(s) 
'__repr__ called' 
>>> str(s) 
'__str__ called'

Acquisition et affectation de la valeur de l'indice : __getitem__, __setitem__

En mettant en œuvre ces deux méthodes , vous pouvez obtenir et attribuer des valeurs aux objets sous la forme telle que X[i], et vous pouvez également utiliser des opérations de découpage sur les objets.

>>> class Indexer: 
  data = [1,2,3,4,5,6] 
  def __getitem__(self,index): 
    return self.data[index] 
  def __setitem__(self,k,v): 
    self.data[k] = v 
    print(self.data) 
>>> i = Indexer() 
>>> i[0] 
1 
>>> i[1:4] 
[2, 3, 4] 
>>> i[0]=10 
[10, 2, 3, 4, 5, 6]

Définir et accéder aux attributs : __getattr__, __setattr__

Nous pouvons surcharger __getattr__ et __setattr__ pour intercepter l'accès d'objecter les membres. __getattr__ est automatiquement appelé lors de l'accès à un membre qui n'existe pas dans l'objet. La méthode __setattr__ est utilisée pour appeler lors de l'initialisation des membres de l'objet, c'est-à-dire que la méthode __setattr__ est appelée lors de la définition de l'élément de __dict__. L'exemple spécifique est le suivant :

class A(): 
  def __init__(self,ax,bx): 
    self.a = ax 
    self.b = bx 
  def f(self): 
    print (self.__dict__) 
  def __getattr__(self,name): 
    print ("__getattr__") 
  def __setattr__(self,name,value): 
    print ("__setattr__") 
    self.__dict__[name] = value 
 
a = A(1,2) 
a.f() 
a.x 
a.x = 3 
a.f()

Le résultat de l'exécution du code ci-dessus est le suivant. À partir du résultat, il peut être vu. que lors de l'accès à la variable x inexistante, elle sera appelée méthode __getattr__ ; lorsque __init__ sera appelée, l'opération d'affectation appellera également la méthode __setattr__.

__setattr__ 
__setattr__ 
{'a': 1, 'b': 2} 
__getattr__ 
__setattr__ 
{'a': 1, 'x': 3, 'b': 2}

Objet itérateur : __iter__, __next__

L'itération en Python peut être effectuée directement. est obtenu en surchargeant la méthode __getitem__, voir l'exemple ci-dessous.

>>> class Indexer: 
...   data = [1,2,3,4,5,6] 
...   def __getitem__(self,index): 
...       return self.data[index] 
...  
>>> x = Indexer() 
>>> for item in x: 
...   print(item) 
...  
1 
2 
3 
4 
5 
6

L'itération peut être réalisée grâce à la méthode ci-dessus, mais ce n'est pas la meilleure façon. L'opération d'itération de Python tentera d'abord d'appeler la méthode __iter__, puis essaiera __getitem__. L'environnement itératif est implémenté en utilisant iter pour essayer de trouver la méthode __iter__, qui renvoie un objet itérateur. Si cette méthode est fournie, Python appellera à plusieurs reprises la méthode next() de l'objet itérateur jusqu'à ce qu'une exception StopIteration se produise. Si __iter__ n'est pas trouvé, Python essaiera d'utiliser le mécanisme __getitem__. Regardons un exemple d'itérateur.

class Next(object): 
  def __init__(self, data=1): 
    self.data = data 
  def __iter__(self): 
    return self 
  def __next__(self): 
    print("__next__ called") 
    if self.data > 5: 
      raise StopIteration 
    else: 
      self.data += 1 
      return self.data 
for i in Next(3): 
  print(i) 
print("-----------") 
n = Next(3) 
i = iter(n) 
while True: 
  try: 
    print(next(i)) 
  except Exception as e: 
    break

Les résultats en cours du programme sont les suivants :

__next__ called 
4 
__next__ called 
5 
__next__ called 
6 
__next__ called 
----------- 
__next__ called 
4 
__next__ called 
5 
__next__ called 
6 
__next__ called

On peut voir qu'une fois les méthodes __iter__ et __next__ implémentées, l'objet peut être itéré via la méthode for in, ou l'objet peut être itéré via les méthodes iter() et next().

Merci d'avoir lu, j'espère que cela pourra vous aider, merci pour votre soutien à ce site !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

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