bonjour, en suivant l'exemple des m=E9taclasses avec python sur
wikipedia : http://fr.wikipedia.org/wiki/M%C3%A9taclasse
J'obtiens l'erreur suivante :
>pythonw -u "test_metaclasse.py"
Traceback (most recent call last):
File "test_metaclasse.py", line 28, in <module>
class A(object):
File "test_metaclasse.py", line 21, in __new__
if type(slot) is type(_trace):
NameError: global name '_trace' is not defined
>Exit code: 1
Et l=E0, comme je d=E9bute, ben j'ai un peu de mal =E0 comprendre... J'ai
beau ajouter "global _trace", rien n'y fait...
File "test_metaclasse.py", line 28, in <module> class A(object): File "test_metaclasse.py", line 21, in __new__ if type(slot) is type(_trace): NameError: global name '_trace' is not defined
Exit code: 1
Il y a effectivement une erreur dans le code de l'exemple. Plusieurs, en fait. Voici une version corrigée (fonctionne ici avec python 2.4.x)
import types
class Tracer(type): def __new__(metacls, name, bases, dct): # définition d'une fonction wrapper pour les méthodes def _wrapper(name, method): # création d'une fonction permettant tracer une méthode def _trace(self, *args, **kwargs): print "(call %s)" % name return method(self, *args, **kwargs) # idiome: faire passer une fonction pour une autre _trace.__name__ = method.__name__ _trace.__doc__ = method.__doc__ #_trace.__dict__._update(_method.__dict__) _trace.__dict__.update(method.__dict__) return _trace
# remplacement de toutes les méthodes par leur équivalent tracé newDct = {} for name, slot in dct.iteritems(): #if type(slot) is type(_trace): if type(slot) is types.FunctionType: #newDct[name] = _wrapper(slot) newDct[name] = _wrapper(name, slot) else: newDct[name] = slot # appel au constructeur de la super classe (type) return type.__new__(metacls, name, bases, newDct)
Et là, comme je débute, ben j'ai un peu de mal à comprendre...
A moins que tu ne sois déjà un développeur expérimenté, les métaclasses ne sont peut-être pas le meilleur point de départ...
File "test_metaclasse.py", line 28, in <module>
class A(object):
File "test_metaclasse.py", line 21, in __new__
if type(slot) is type(_trace):
NameError: global name '_trace' is not defined
Exit code: 1
Il y a effectivement une erreur dans le code de l'exemple. Plusieurs, en
fait. Voici une version corrigée (fonctionne ici avec python 2.4.x)
import types
class Tracer(type):
def __new__(metacls, name, bases, dct):
# définition d'une fonction wrapper pour les méthodes
def _wrapper(name, method):
# création d'une fonction permettant tracer une méthode
def _trace(self, *args, **kwargs):
print "(call %s)" % name
return method(self, *args, **kwargs)
# idiome: faire passer une fonction pour une autre
_trace.__name__ = method.__name__
_trace.__doc__ = method.__doc__
#_trace.__dict__._update(_method.__dict__)
_trace.__dict__.update(method.__dict__)
return _trace
# remplacement de toutes les méthodes par leur équivalent tracé
newDct = {}
for name, slot in dct.iteritems():
#if type(slot) is type(_trace):
if type(slot) is types.FunctionType:
#newDct[name] = _wrapper(slot)
newDct[name] = _wrapper(name, slot)
else:
newDct[name] = slot
# appel au constructeur de la super classe (type)
return type.__new__(metacls, name, bases, newDct)
Et là, comme je débute, ben j'ai un peu de mal à comprendre...
A moins que tu ne sois déjà un développeur expérimenté, les métaclasses
ne sont peut-être pas le meilleur point de départ...
File "test_metaclasse.py", line 28, in <module> class A(object): File "test_metaclasse.py", line 21, in __new__ if type(slot) is type(_trace): NameError: global name '_trace' is not defined
Exit code: 1
Il y a effectivement une erreur dans le code de l'exemple. Plusieurs, en fait. Voici une version corrigée (fonctionne ici avec python 2.4.x)
import types
class Tracer(type): def __new__(metacls, name, bases, dct): # définition d'une fonction wrapper pour les méthodes def _wrapper(name, method): # création d'une fonction permettant tracer une méthode def _trace(self, *args, **kwargs): print "(call %s)" % name return method(self, *args, **kwargs) # idiome: faire passer une fonction pour une autre _trace.__name__ = method.__name__ _trace.__doc__ = method.__doc__ #_trace.__dict__._update(_method.__dict__) _trace.__dict__.update(method.__dict__) return _trace
# remplacement de toutes les méthodes par leur équivalent tracé newDct = {} for name, slot in dct.iteritems(): #if type(slot) is type(_trace): if type(slot) is types.FunctionType: #newDct[name] = _wrapper(slot) newDct[name] = _wrapper(name, slot) else: newDct[name] = slot # appel au constructeur de la super classe (type) return type.__new__(metacls, name, bases, newDct)
Et là, comme je débute, ben j'ai un peu de mal à comprendre...
A moins que tu ne sois déjà un développeur expérimenté, les métaclasses ne sont peut-être pas le meilleur point de départ...
-- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in ''.split('@')])"
Jean-Marc Pouchoulon
Bonjour, Une question : Comment a.get() déclenche l'appel à _trace. Je comprend que __new__ et __init__ soient appelés lors de la contruction de la classe , mais lors de l'accès à a.get que se passe t -il ? (appel de getattribute mais ensuite ? )
jmp
evaisse wrote:
bonjour, en suivant l'exemple des métaclasses avec python sur wikipedia : http://fr.wikipedia.org/wiki/M%C3%A9taclasse
File "test_metaclasse.py", line 28, in <module> class A(object): File "test_metaclasse.py", line 21, in __new__ if type(slot) is type(_trace): NameError: global name '_trace' is not defined
Exit code: 1
Il y a effectivement une erreur dans le code de l'exemple. Plusieurs, en fait. Voici une version corrigée (fonctionne ici avec python 2.4.x)
import types
class Tracer(type): def __new__(metacls, name, bases, dct): # définition d'une fonction wrapper pour les méthodes def _wrapper(name, method): # création d'une fonction permettant tracer une méthode def _trace(self, *args, **kwargs): print "(call %s)" % name return method(self, *args, **kwargs) # idiome: faire passer une fonction pour une autre _trace.__name__ = method.__name__ _trace.__doc__ = method.__doc__ #_trace.__dict__._update(_method.__dict__) _trace.__dict__.update(method.__dict__) return _trace
# remplacement de toutes les méthodes par leur équivalent tracé newDct = {} for name, slot in dct.iteritems(): #if type(slot) is type(_trace): if type(slot) is types.FunctionType: #newDct[name] = _wrapper(slot) newDct[name] = _wrapper(name, slot) else: newDct[name] = slot # appel au constructeur de la super classe (type) return type.__new__(metacls, name, bases, newDct)
Et là, comme je débute, ben j'ai un peu de mal à comprendre...
A moins que tu ne sois déjà un développeur expérimenté, les métaclasses ne sont peut-être pas le meilleur point de départ...
Bonjour,
Une question :
Comment a.get() déclenche l'appel à _trace.
Je comprend que __new__ et __init__ soient appelés lors de la
contruction de la classe , mais lors de l'accès à a.get que se passe t -il ?
(appel de getattribute mais ensuite ? )
jmp
evaisse wrote:
bonjour, en suivant l'exemple des métaclasses avec python sur
wikipedia : http://fr.wikipedia.org/wiki/M%C3%A9taclasse
File "test_metaclasse.py", line 28, in <module>
class A(object):
File "test_metaclasse.py", line 21, in __new__
if type(slot) is type(_trace):
NameError: global name '_trace' is not defined
Exit code: 1
Il y a effectivement une erreur dans le code de l'exemple. Plusieurs, en
fait. Voici une version corrigée (fonctionne ici avec python 2.4.x)
import types
class Tracer(type):
def __new__(metacls, name, bases, dct):
# définition d'une fonction wrapper pour les méthodes
def _wrapper(name, method):
# création d'une fonction permettant tracer une méthode
def _trace(self, *args, **kwargs):
print "(call %s)" % name
return method(self, *args, **kwargs)
# idiome: faire passer une fonction pour une autre
_trace.__name__ = method.__name__
_trace.__doc__ = method.__doc__
#_trace.__dict__._update(_method.__dict__)
_trace.__dict__.update(method.__dict__)
return _trace
# remplacement de toutes les méthodes par leur équivalent tracé
newDct = {}
for name, slot in dct.iteritems():
#if type(slot) is type(_trace):
if type(slot) is types.FunctionType:
#newDct[name] = _wrapper(slot)
newDct[name] = _wrapper(name, slot)
else:
newDct[name] = slot
# appel au constructeur de la super classe (type)
return type.__new__(metacls, name, bases, newDct)
Et là, comme je débute, ben j'ai un peu de mal à comprendre...
A moins que tu ne sois déjà un développeur expérimenté, les métaclasses
ne sont peut-être pas le meilleur point de départ...
Bonjour, Une question : Comment a.get() déclenche l'appel à _trace. Je comprend que __new__ et __init__ soient appelés lors de la contruction de la classe , mais lors de l'accès à a.get que se passe t -il ? (appel de getattribute mais ensuite ? )
jmp
evaisse wrote:
bonjour, en suivant l'exemple des métaclasses avec python sur wikipedia : http://fr.wikipedia.org/wiki/M%C3%A9taclasse
File "test_metaclasse.py", line 28, in <module> class A(object): File "test_metaclasse.py", line 21, in __new__ if type(slot) is type(_trace): NameError: global name '_trace' is not defined
Exit code: 1
Il y a effectivement une erreur dans le code de l'exemple. Plusieurs, en fait. Voici une version corrigée (fonctionne ici avec python 2.4.x)
import types
class Tracer(type): def __new__(metacls, name, bases, dct): # définition d'une fonction wrapper pour les méthodes def _wrapper(name, method): # création d'une fonction permettant tracer une méthode def _trace(self, *args, **kwargs): print "(call %s)" % name return method(self, *args, **kwargs) # idiome: faire passer une fonction pour une autre _trace.__name__ = method.__name__ _trace.__doc__ = method.__doc__ #_trace.__dict__._update(_method.__dict__) _trace.__dict__.update(method.__dict__) return _trace
# remplacement de toutes les méthodes par leur équivalent tracé newDct = {} for name, slot in dct.iteritems(): #if type(slot) is type(_trace): if type(slot) is types.FunctionType: #newDct[name] = _wrapper(slot) newDct[name] = _wrapper(name, slot) else: newDct[name] = slot # appel au constructeur de la super classe (type) return type.__new__(metacls, name, bases, newDct)
Et là, comme je débute, ben j'ai un peu de mal à comprendre...
A moins que tu ne sois déjà un développeur expérimenté, les métaclasses ne sont peut-être pas le meilleur point de départ...
Splendid !! merci, avec ça je devrais pouvoir m'en sortir. J'utilise python2.5 et ça fonctionne. Plus qu'à comprendre comment maintenant...
Bonjour, Une question : Comment a.get() déclenche l'appel à _trace. Je comprend que __new__ et __init__ soient appelés lors de la contruction de la classe , mais lors de l'accès à a.get que se passe t -il ? (appel de getattribute mais ensuite ? )
jmp
evaisse wrote:
bonjour, en suivant l'exemple des métaclasses avec python sur wikipedia : http://fr.wikipedia.org/wiki/M%C3%A9taclasse
File "test_metaclasse.py", line 28, in <module> class A(object): File "test_metaclasse.py", line 21, in __new__ if type(slot) is type(_trace): NameError: global name '_trace' is not defined
Exit code: 1
Il y a effectivement une erreur dans le code de l'exemple. Plusieurs, en fait. Voici une version corrigée (fonctionne ici avec python 2.4.x)
import types
class Tracer(type): def __new__(metacls, name, bases, dct): # définition d'une fonction wrapper pour les méthodes def _wrapper(name, method): # création d'une fonction permettant tracer une méthode def _trace(self, *args, **kwargs): print "(call %s)" % name return method(self, *args, **kwargs) # idiome: faire passer une fonction pour une autre _trace.__name__ = method.__name__ _trace.__doc__ = method.__doc__ #_trace.__dict__._update(_method.__dict__) _trace.__dict__.update(method.__dict__) return _trace
# remplacement de toutes les méthodes par leur équivalent t racé newDct = {} for name, slot in dct.iteritems(): #if type(slot) is type(_trace): if type(slot) is types.FunctionType: #newDct[name] = _wrapper(slot) newDct[name] = _wrapper(name, slot) else: newDct[name] = slot # appel au constructeur de la super classe (type) return type.__new__(metacls, name, bases, newDct)
Et là, comme je débute, ben j'ai un peu de mal à comprendre...
A moins que tu ne sois déjà un développeur expérimenté, les m étaclasses ne sont peut-être pas le meilleur point de départ...
Splendid !!
merci, avec ça je devrais pouvoir m'en sortir. J'utilise python2.5 et
ça fonctionne.
Plus qu'à comprendre comment maintenant...
Bonjour,
Une question :
Comment a.get() déclenche l'appel à _trace.
Je comprend que __new__ et __init__ soient appelés lors de la
contruction de la classe , mais lors de l'accès à a.get que se passe t -il ?
(appel de getattribute mais ensuite ? )
jmp
evaisse wrote:
bonjour, en suivant l'exemple des métaclasses avec python sur
wikipedia : http://fr.wikipedia.org/wiki/M%C3%A9taclasse
File "test_metaclasse.py", line 28, in <module>
class A(object):
File "test_metaclasse.py", line 21, in __new__
if type(slot) is type(_trace):
NameError: global name '_trace' is not defined
Exit code: 1
Il y a effectivement une erreur dans le code de l'exemple. Plusieurs, en
fait. Voici une version corrigée (fonctionne ici avec python 2.4.x)
import types
class Tracer(type):
def __new__(metacls, name, bases, dct):
# définition d'une fonction wrapper pour les méthodes
def _wrapper(name, method):
# création d'une fonction permettant tracer une méthode
def _trace(self, *args, **kwargs):
print "(call %s)" % name
return method(self, *args, **kwargs)
# idiome: faire passer une fonction pour une autre
_trace.__name__ = method.__name__
_trace.__doc__ = method.__doc__
#_trace.__dict__._update(_method.__dict__)
_trace.__dict__.update(method.__dict__)
return _trace
# remplacement de toutes les méthodes par leur équivalent t racé
newDct = {}
for name, slot in dct.iteritems():
#if type(slot) is type(_trace):
if type(slot) is types.FunctionType:
#newDct[name] = _wrapper(slot)
newDct[name] = _wrapper(name, slot)
else:
newDct[name] = slot
# appel au constructeur de la super classe (type)
return type.__new__(metacls, name, bases, newDct)
Et là, comme je débute, ben j'ai un peu de mal à comprendre...
A moins que tu ne sois déjà un développeur expérimenté, les m étaclasses
ne sont peut-être pas le meilleur point de départ...
Splendid !! merci, avec ça je devrais pouvoir m'en sortir. J'utilise python2.5 et ça fonctionne. Plus qu'à comprendre comment maintenant...
Bonjour, Une question : Comment a.get() déclenche l'appel à _trace. Je comprend que __new__ et __init__ soient appelés lors de la contruction de la classe , mais lors de l'accès à a.get que se passe t -il ? (appel de getattribute mais ensuite ? )
jmp
evaisse wrote:
bonjour, en suivant l'exemple des métaclasses avec python sur wikipedia : http://fr.wikipedia.org/wiki/M%C3%A9taclasse
File "test_metaclasse.py", line 28, in <module> class A(object): File "test_metaclasse.py", line 21, in __new__ if type(slot) is type(_trace): NameError: global name '_trace' is not defined
Exit code: 1
Il y a effectivement une erreur dans le code de l'exemple. Plusieurs, en fait. Voici une version corrigée (fonctionne ici avec python 2.4.x)
import types
class Tracer(type): def __new__(metacls, name, bases, dct): # définition d'une fonction wrapper pour les méthodes def _wrapper(name, method): # création d'une fonction permettant tracer une méthode def _trace(self, *args, **kwargs): print "(call %s)" % name return method(self, *args, **kwargs) # idiome: faire passer une fonction pour une autre _trace.__name__ = method.__name__ _trace.__doc__ = method.__doc__ #_trace.__dict__._update(_method.__dict__) _trace.__dict__.update(method.__dict__) return _trace
# remplacement de toutes les méthodes par leur équivalent t racé newDct = {} for name, slot in dct.iteritems(): #if type(slot) is type(_trace): if type(slot) is types.FunctionType: #newDct[name] = _wrapper(slot) newDct[name] = _wrapper(name, slot) else: newDct[name] = slot # appel au constructeur de la super classe (type) return type.__new__(metacls, name, bases, newDct)
Et là, comme je débute, ben j'ai un peu de mal à comprendre...
A moins que tu ne sois déjà un développeur expérimenté, les m étaclasses ne sont peut-être pas le meilleur point de départ...
print "(call %s)" % name return method(self, *args, **kwargs)
magique...
Bruno Desthuilliers
Bonjour, Une question : Comment a.get() déclenche l'appel à _trace.
C'est le principe des décorateurs. La fonction d'origine est remplacée par une autre fonction - en l'occurrence une fermeture (une fonction qui trimballe avec elle l'environnement dans le quel elle a été définie).
Je comprend que __new__ et __init__ soient appelés lors de la contruction de la classe , mais lors de l'accès à a.get que se passe t -il ? (appel de getattribute mais ensuite ? )
Il ne se passe rien de spécial à ce moment - c'est lors de la création de l'objet class A que les fonctions définies dans le block class (et donc passée en dernier argument au constructeur de la metaclasse sous la forme d'un dictionnaire, avec les autres attributs définis au niveau de la classe) sont remplacées par la fermeture (fonction _trace) retournée par la fonction _wrapper.
En l'occurrence, on obtiendrait un résultat identique avec un simple décorateur - à condition bien sûr de l'appliquer à toutes les fonctions concernées.
Bonjour,
Une question :
Comment a.get() déclenche l'appel à _trace.
C'est le principe des décorateurs. La fonction d'origine est remplacée
par une autre fonction - en l'occurrence une fermeture (une fonction qui
trimballe avec elle l'environnement dans le quel elle a été définie).
Je comprend que __new__ et __init__ soient appelés lors de la
contruction de la classe , mais lors de l'accès à a.get que se passe t
-il ?
(appel de getattribute mais ensuite ? )
Il ne se passe rien de spécial à ce moment - c'est lors de la création
de l'objet class A que les fonctions définies dans le block class (et
donc passée en dernier argument au constructeur de la metaclasse sous la
forme d'un dictionnaire, avec les autres attributs définis au niveau de
la classe) sont remplacées par la fermeture (fonction _trace) retournée
par la fonction _wrapper.
En l'occurrence, on obtiendrait un résultat identique avec un simple
décorateur - à condition bien sûr de l'appliquer à toutes les fonctions
concernées.
Bonjour, Une question : Comment a.get() déclenche l'appel à _trace.
C'est le principe des décorateurs. La fonction d'origine est remplacée par une autre fonction - en l'occurrence une fermeture (une fonction qui trimballe avec elle l'environnement dans le quel elle a été définie).
Je comprend que __new__ et __init__ soient appelés lors de la contruction de la classe , mais lors de l'accès à a.get que se passe t -il ? (appel de getattribute mais ensuite ? )
Il ne se passe rien de spécial à ce moment - c'est lors de la création de l'objet class A que les fonctions définies dans le block class (et donc passée en dernier argument au constructeur de la metaclasse sous la forme d'un dictionnaire, avec les autres attributs définis au niveau de la classe) sont remplacées par la fermeture (fonction _trace) retournée par la fonction _wrapper.
En l'occurrence, on obtiendrait un résultat identique avec un simple décorateur - à condition bien sûr de l'appliquer à toutes les fonctions concernées.
jean-marc pouchoulon
En l'occurrence, on obtiendrait un résultat identique avec un simple décorateur - à condition bien sûr de l'appliquer à toutes les fonctions concernées.
Ok et merci
En l'occurrence, on obtiendrait un résultat identique avec un simple
décorateur - à condition bien sûr de l'appliquer à toutes les fonctions
concernées.
En l'occurrence, on obtiendrait un résultat identique avec un simple décorateur - à condition bien sûr de l'appliquer à toutes les fonctions concernées.