Création d'un type Python (classe) avec des méthodes en tant qu'objets appelables

Par exemple, si je fais cela pour un classmethod, tout se passe comme prévu et le réel clsest transmis au X.__call___:

class X:
def __call__(self, *args, **kwargs):
print(self)
print(args)
print(kwargs)
print("Hi")
t = type("Y", (object,), dict(x=classmethod(X())))
ti = t()
ti.x()

Les sorties

<__main__.X object at 0x7f835ec664c0>
(<class '__main__.Y'>,)
{}
Hi

Mais lorsque j'essaie de créer un Ytype avec une xméthode en tant qu'interpréteur régulier (non statique), il ne semble pas passer l' Yinstance réelle lors de l'exécution de X.__call__. Par example:

class X:
def __call__(self, *args, **kwargs):
print(self)
print(args)
print(kwargs)
print("Hi")
t = type("Y", (object,), dict(x=X()))
ti = t()
ti.x()

Les sorties:

<__main__.X object at 0x7fdce385e4c0>
()
{}
Hi

Quelqu'un a-t-il une idée de la raison pour laquelle l'instance n'est pas Ytransmise, mais dans le cas d'un argument, classmethodl' clsargument est-il transmis? Merci!


Solution du problème

La solution que j'ai trouvée était de remplacer également le __get__. Mais encore une fois, ce n'est pas comme je l'avais prévu, et il y a un peu de surcharge dans get.

class X:
def __init__(self):
self.holder = None
def __get__(self, holder, holder_type):
self.holder = holder
return self
def __call__(self, *args, **kwargs):
print(self)
print(self.holder)
print(args)
print(kwargs)
print("Hi")
t = type("Y", (object,), dict(x=X()))
ti = t()
ti.x()

Commentaires

Posts les plus consultés de ce blog

Erreur Symfony : "Une exception a été levée lors du rendu d'un modèle"

Détecter les appuis sur les touches fléchées en JavaScript

Une chaîne vide donne "Des erreurs ont été détectées dans les arguments de la ligne de commande, veuillez vous assurer que tous les arguments sont correctement définis"