Maison > Article > développement back-end > Une brève introduction aux trois méthodes __init__, __new__ et __call__ en python
Cet article vous présente principalement les informations pertinentes sur les méthodes __init__, __new__ et __call__ en Python. L'article les présente en détail à travers un exemple de code, qui a une certaine valeur de référence et d'apprentissage pour tous les amis qui en ont besoin. étude de référence, suivons l'éditeur et jetons un œil.
Avant-propos
Cet article vous présente principalement le contenu pertinent sur les méthodes __init__, __new__ et __call__ en python, partagez-le pour Veuillez vous référer pour référence. Pas grand chose à dire ci-dessous, jetons un coup d'œil à l'introduction détaillée :
Tout a un processus depuis la création, l'utilisation jusqu'à la mort dans le modèle de programmation orienté objet du langage de programmation, les objets. ont également un sort similaire : création, initialisation, utilisation et garbage collection. Différentes étapes sont exécutées par différentes méthodes (rôles).
Lors de la définition d'une classe, la méthode la plus couramment utilisée est la méthode __init__, tandis que __new__ et __call__ sont utilisées moins fréquemment. Cet article tente de vous aider à comprendre les scénarios d'utilisation et d'application corrects de ces trois méthodes. séparément.
Je ne parlerai pas trop des classes de style nouveau et des classes de style ancien de Python dans cet article, car les classes de style ancien sont un concept dans Python2, et presque plus personne n'utilisera de classes de style ancien. . Les classes de nouveau style doivent hériter explicitement de l'objet. Dans Python3, il existe uniquement des classes de nouveau style, qui héritent de l'objet par défaut et n'ont pas besoin d'être explicitement spécifiées. Les codes de cet article sont tous abordés sur la base de Python3.
Méthode __init__
La méthode __init__ est responsable de l'initialisation de l'objet Avant que le système n'exécute cette méthode, l'objet existe déjà. , sinon Que initialiser ? Regardons d'abord l'exemple :
# class A(object): python2 必须显示地继承object class A: def __init__(self): print("__init__ ") super(A, self).__init__() def __new__(cls): print("__new__ ") return super(A, cls).__new__(cls) def __call__(self): # 可以定义任意参数 print('__call__ ') A()
Sortie
__new__ __init__
À partir du résultat de sortie, __new__ méthode Il est appelé en premier, renvoie un objet instance, puis __init__ est appelé. La méthode __call__ n'a pas été appelée. Laissons cela pour la fin. Parlons d'abord des deux premières méthodes, légèrement réécrites comme :
def __init__(self): print("__init__ ") print(self) super(A, self).__init__() def __new__(cls): print("__new__ ") self = super(A, cls).__new__(cls) print(self) return self
Sortie :
__new__ <__main__.A object at 0x1007a95f8> __init__ <__main__.A object at 0x1007a95f8>À en juger par le résultat, la valeur de retour de la méthode __new__ est l'objet instance de la classe. Cet objet instance sera transmis au paramètre self défini dans __init__. méthode afin que l'instance L'objet puisse être initialisé correctement. Si la méthode __new__ ne renvoie pas de valeur (ou renvoie None), alors __init__ ne sera pas appelé, car l'objet instance n'a pas été créé et l'appel à init n'a aucun sens. Python stipule également que __init__ ne peut renvoyer qu'une valeur None, sinon une erreur sera signalée. C'est à chacun d'essayer. La méthode __init__ peut être utilisée pour effectuer certains travaux d'initialisation, comme l'initialisation de l'état de l'objet instance :
def __init__(self, a, b): self.a = a self.b = b super(A, self).__init__()De plus, dans le Méthode __init__ Les paramètres définis à l'exception de self doivent être cohérents ou équivalents aux paramètres de la méthode __new__ à l'exception du paramètre cls.
class B: def __init__(self, *args, **kwargs): print("init", args, kwargs) def __new__(cls, *args, **kwargs): print("new", args, kwargs) return super().__new__(cls) B(1, 2, 3) # 输出 new (1, 2, 3) {} init (1, 2, 3) {}
__new__ méthode
Généralement, nous ne remplacerons pas cette méthode à moins que vous sachiez exactement comment pour le faire, et quand vous en soucierez-vous ? Il est utilisé comme constructeur pour créer des objets. C'est une fonction d'usine dédiée à la production d'objets d'instance. L’un des modèles de conception les plus connus, le modèle singleton, peut être implémenté grâce à cette méthode. Vous pouvez l'utiliser lorsque vous écrivez vous-même du code au niveau du framework. Nous pouvons également trouver ses scénarios d'application à partir de code open source, comme le micro-framework Web Bootle.class BaseController(object): _singleton = None def __new__(cls, *a, **k): if not cls._singleton: cls._singleton = object.__new__(cls, *a, **k) return cls._singletonCe code provient de https://github.com/bottlepy/bottle/blob/release-0.6/bottle.pyCe La méthode __new__ est un moyen d'implémenter le mode singleton. Si l'objet instance existe, renvoyez simplement l'instance. S'il n'existe pas, créez d'abord une instance, puis revenez. Bien sûr, il existe plusieurs façons d'implémenter le modèle singleton. Le Zen de Python dit : Il devrait y avoir une - et de préférence une seule - manière évidente de le faire.Utilisez une seule méthode, il est préférable de n'avoir qu'une seule façon de faire une chose
Méthode __call__
À propos de la méthode __call__ , non Ne mentionnons pas d'abord un concept, c'est-à-dire les objets appelables. Nos fonctions personnalisées habituelles, nos fonctions intégrées et nos classes sont toutes des objets appelables, mais tout ce qui peut appliquer une paire de crochets () à un objet peut être appelé. un objet appelable. Vous pouvez utiliser la fonction callable pour déterminer si l'objet est un objet appelable. Si la méthode __call__ est implémentée dans la classe, alors l'objet instance deviendra également un objet appelable. au début. Cet exemple :a = A() print(callable(a)) # Truea est un objet d'instance et également un objet appelable, alors je peux l'appeler comme une fonction. Essayez :
a() # __call__
很神奇不是,实例对象也可以像函数一样作为可调用对象来用,那么,这个特点在什么场景用得上呢?这个要结合类的特性来说,类可以记录数据(属性),而函数不行(闭包某种意义上也可行),利用这种特性可以实现基于类的装饰器,在类里面记录状态,比如,下面这个例子用于记录函数被调用的次数:
class Counter: def __init__(self, func): self.func = func self.count = 0 def __call__(self, *args, **kwargs): self.count += 1 return self.func(*args, **kwargs) @Counter def foo(): pass for i in range(10): foo() print(foo.count) # 10
在 Bottle 中也有 call 方法 的使用案例,另外,stackoverflow 也有一些关于 call 的实践例子,推荐看看,如果你的项目中,需要更加抽象化、框架代码,那么这些高级特性往往能发挥出它作用。
总结
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!