bonjour,
Pour définir la classe d'une classe on utilise la
méta-classe.
ex :
class MetaClass(type):
def ...
class MaClasse:
__metaclass__ = MetaClass
def ...
Mais, est-il possible de faire de même pour une fonction ?
def maFunc(args):
__que_dois_je_mettre__
bonjour,
Pour définir la classe d'une classe on utilise la
méta-classe.
ex :
class MetaClass(type):
def ...
class MaClasse:
__metaclass__ = MetaClass
def ...
Mais, est-il possible de faire de même pour une fonction ?
def maFunc(args):
__que_dois_je_mettre__
bonjour,
Pour définir la classe d'une classe on utilise la
méta-classe.
ex :
class MetaClass(type):
def ...
class MaClasse:
__metaclass__ = MetaClass
def ...
Mais, est-il possible de faire de même pour une fonction ?
def maFunc(args):
__que_dois_je_mettre__
Mais, est-il possible de faire de même pour une fonction ?
Pas tout à fait. Une fonction est une instance de la classe function.
Cette classe a la particularité de définir la méthode __call__. Rien
n'empêche, bien sûr, d'autres classes de définir cette même méthode.
def maFunc(args):
__que_dois_je_mettre__
class MaFunc(object):
__metaclass__ = OnPeutBienSurCombiner
def __call__(self):
print "allo ?"
Oui, bien sûr, on peut faire ça, mais je souhaiterais le faire
maFunc = MaFunc()
maFunc()
Attention par contre, si tu veux pouvoir utiliser maFunc comme méthode,
il faut que MaFunc implémente correctement le protocole descripteur.
HTH
Mais, est-il possible de faire de même pour une fonction ?
Pas tout à fait. Une fonction est une instance de la classe function.
Cette classe a la particularité de définir la méthode __call__. Rien
n'empêche, bien sûr, d'autres classes de définir cette même méthode.
def maFunc(args):
__que_dois_je_mettre__
class MaFunc(object):
__metaclass__ = OnPeutBienSurCombiner
def __call__(self):
print "allo ?"
Oui, bien sûr, on peut faire ça, mais je souhaiterais le faire
maFunc = MaFunc()
maFunc()
Attention par contre, si tu veux pouvoir utiliser maFunc comme méthode,
il faut que MaFunc implémente correctement le protocole descripteur.
HTH
Mais, est-il possible de faire de même pour une fonction ?
Pas tout à fait. Une fonction est une instance de la classe function.
Cette classe a la particularité de définir la méthode __call__. Rien
n'empêche, bien sûr, d'autres classes de définir cette même méthode.
def maFunc(args):
__que_dois_je_mettre__
class MaFunc(object):
__metaclass__ = OnPeutBienSurCombiner
def __call__(self):
print "allo ?"
Oui, bien sûr, on peut faire ça, mais je souhaiterais le faire
maFunc = MaFunc()
maFunc()
Attention par contre, si tu veux pouvoir utiliser maFunc comme méthode,
il faut que MaFunc implémente correctement le protocole descripteur.
HTH
Mais, est-il possible de faire de même pour une fonction ?
Pas tout à fait. Une fonction est une instance de la classe function.
Cette classe a la particularité de définir la méthode __call__. Rien
n'empêche, bien sûr, d'autres classes de définir cette même méthode.
Mais alors, ne serait-il pas possible à la classe fonction de lui dire
d'utiliser MaMetaClasse comme metaclasse ?
Mais, est-il possible de faire de même pour une fonction ?
Pas tout à fait. Une fonction est une instance de la classe function.
Cette classe a la particularité de définir la méthode __call__. Rien
n'empêche, bien sûr, d'autres classes de définir cette même méthode.
Mais alors, ne serait-il pas possible à la classe fonction de lui dire
d'utiliser MaMetaClasse comme metaclasse ?
Mais, est-il possible de faire de même pour une fonction ?
Pas tout à fait. Une fonction est une instance de la classe function.
Cette classe a la particularité de définir la méthode __call__. Rien
n'empêche, bien sûr, d'autres classes de définir cette même méthode.
Mais alors, ne serait-il pas possible à la classe fonction de lui dire
d'utiliser MaMetaClasse comme metaclasse ?
Mais, est-il possible de faire de même pour une fonction ?
Pas tout à fait. Une fonction est une instance de la classe function.
Cette classe a la particularité de définir la méthode __call__. Rien
n'empêche, bien sûr, d'autres classes de définir cette même méthode.
Mais alors, ne serait-il pas possible à la classe fonction de lui dire
d'utiliser MaMetaClasse comme metaclasse ?
Tu a essayé ?-)
Non, ce n'est pas possible. Et ça n'aurait pas beaucoup de sens par
ailleurs : les metaclasses sont essentiellement utiles pour customiser
le processus de création des classes - or, la classe function est *déjà*
construite quand tu va vouloir en changer la metaclasse.
Accessoirement, et sis ce n'est pas indiscret, pourquoi veux-tu une
autre metaclasse pour les fonctions?
Non, ce n'est pas indiscret.
Mais, est-il possible de faire de même pour une fonction ?
Pas tout à fait. Une fonction est une instance de la classe function.
Cette classe a la particularité de définir la méthode __call__. Rien
n'empêche, bien sûr, d'autres classes de définir cette même méthode.
Mais alors, ne serait-il pas possible à la classe fonction de lui dire
d'utiliser MaMetaClasse comme metaclasse ?
Tu a essayé ?-)
Non, ce n'est pas possible. Et ça n'aurait pas beaucoup de sens par
ailleurs : les metaclasses sont essentiellement utiles pour customiser
le processus de création des classes - or, la classe function est *déjà*
construite quand tu va vouloir en changer la metaclasse.
Accessoirement, et sis ce n'est pas indiscret, pourquoi veux-tu une
autre metaclasse pour les fonctions?
Non, ce n'est pas indiscret.
Mais, est-il possible de faire de même pour une fonction ?
Pas tout à fait. Une fonction est une instance de la classe function.
Cette classe a la particularité de définir la méthode __call__. Rien
n'empêche, bien sûr, d'autres classes de définir cette même méthode.
Mais alors, ne serait-il pas possible à la classe fonction de lui dire
d'utiliser MaMetaClasse comme metaclasse ?
Tu a essayé ?-)
Non, ce n'est pas possible. Et ça n'aurait pas beaucoup de sens par
ailleurs : les metaclasses sont essentiellement utiles pour customiser
le processus de création des classes - or, la classe function est *déjà*
construite quand tu va vouloir en changer la metaclasse.
Accessoirement, et sis ce n'est pas indiscret, pourquoi veux-tu une
autre metaclasse pour les fonctions?
Non, ce n'est pas indiscret.
Bruno Desthuilliers wrote:Mais, est-il possible de faire de même pour une fonction ?
Pas tout à fait. Une fonction est une instance de la classe
function. Cette classe a la particularité de définir la méthode
__call__. Rien n'empêche, bien sûr, d'autres classes de définir
cette même méthode.
Mais alors, ne serait-il pas possible à la classe fonction de lui dire
d'utiliser MaMetaClasse comme metaclasse ?
Tu a essayé ?-)
Non, ce n'est pas possible. Et ça n'aurait pas beaucoup de sens par
ailleurs : les metaclasses sont essentiellement utiles pour customiser
le processus de création des classes - or, la classe function est
*déjà* construite quand tu va vouloir en changer la metaclasse.
Accessoirement, et sis ce n'est pas indiscret, pourquoi veux-tu une
autre metaclasse pour les fonctions?
Non, ce n'est pas indiscret.
J'utilise ce principe pour appliquer la programmation par contrat :
pré-conditions, post-conditions et invariants de méthodes ou de classes.
Je sais, ça existe déjà (pycontract qui utilise __getattr__) mais
les exceptions ne sont pas très parlantes et on est obligé de spécifier
tous les modules que l'on veut traiter. Bref j'ai voulu faire qqchose
à ma sauce à base de métaclasses et ça marche très bien.
Par exemple :
class Test:
"""
inv:
self.j >0
"""
__metaclass__ = MetaContract
j = 1
k = None
def __init__(self):
"""
post:
len(self.k)==3
"""
self.k = [1,2,3]
def test(self, f=array(()),i=1, toto=1):
"""
This is a test function
pre:
isinstance(i, int)
isinstance(f,type(array(())))
post:
__return__ == 1
self.i == 1
len(f)==3
inv:
self.j == 1
isinstance(self.j,int)
"""
self.i = 1
self.j = 1
return 1
m = Test()
m.test(array((1,2,3)), i=1.0)
donne --->
Traceback (most recent call last):
File "../etc/metacontract.py", line 228, in ?
main()
File "../etc/metacontract.py", line 217, in main
m.test(array((1,2,3)), i=1.0)
File "../etc/metacontract.py", line 107, in _trace
raise ValueError(condition+' condition assertion
('+class_or_method+' contract line %d): %s'%(i, code_line,))
ValueError: Pre- condition assertion (method contract line 2):
isinstance(i, int)
Le problème est que je ne peux pas appliquer ce principe aux fonctions...
Bruno Desthuilliers wrote:
Mais, est-il possible de faire de même pour une fonction ?
Pas tout à fait. Une fonction est une instance de la classe
function. Cette classe a la particularité de définir la méthode
__call__. Rien n'empêche, bien sûr, d'autres classes de définir
cette même méthode.
Mais alors, ne serait-il pas possible à la classe fonction de lui dire
d'utiliser MaMetaClasse comme metaclasse ?
Tu a essayé ?-)
Non, ce n'est pas possible. Et ça n'aurait pas beaucoup de sens par
ailleurs : les metaclasses sont essentiellement utiles pour customiser
le processus de création des classes - or, la classe function est
*déjà* construite quand tu va vouloir en changer la metaclasse.
Accessoirement, et sis ce n'est pas indiscret, pourquoi veux-tu une
autre metaclasse pour les fonctions?
Non, ce n'est pas indiscret.
J'utilise ce principe pour appliquer la programmation par contrat :
pré-conditions, post-conditions et invariants de méthodes ou de classes.
Je sais, ça existe déjà (pycontract qui utilise __getattr__) mais
les exceptions ne sont pas très parlantes et on est obligé de spécifier
tous les modules que l'on veut traiter. Bref j'ai voulu faire qqchose
à ma sauce à base de métaclasses et ça marche très bien.
Par exemple :
class Test:
"""
inv:
self.j >0
"""
__metaclass__ = MetaContract
j = 1
k = None
def __init__(self):
"""
post:
len(self.k)==3
"""
self.k = [1,2,3]
def test(self, f=array(()),i=1, toto=1):
"""
This is a test function
pre:
isinstance(i, int)
isinstance(f,type(array(())))
post:
__return__ == 1
self.i == 1
len(f)==3
inv:
self.j == 1
isinstance(self.j,int)
"""
self.i = 1
self.j = 1
return 1
m = Test()
m.test(array((1,2,3)), i=1.0)
donne --->
Traceback (most recent call last):
File "../etc/metacontract.py", line 228, in ?
main()
File "../etc/metacontract.py", line 217, in main
m.test(array((1,2,3)), i=1.0)
File "../etc/metacontract.py", line 107, in _trace
raise ValueError(condition+' condition assertion
('+class_or_method+' contract line %d): %s'%(i, code_line,))
ValueError: Pre- condition assertion (method contract line 2):
isinstance(i, int)
Le problème est que je ne peux pas appliquer ce principe aux fonctions...
Bruno Desthuilliers wrote:Mais, est-il possible de faire de même pour une fonction ?
Pas tout à fait. Une fonction est une instance de la classe
function. Cette classe a la particularité de définir la méthode
__call__. Rien n'empêche, bien sûr, d'autres classes de définir
cette même méthode.
Mais alors, ne serait-il pas possible à la classe fonction de lui dire
d'utiliser MaMetaClasse comme metaclasse ?
Tu a essayé ?-)
Non, ce n'est pas possible. Et ça n'aurait pas beaucoup de sens par
ailleurs : les metaclasses sont essentiellement utiles pour customiser
le processus de création des classes - or, la classe function est
*déjà* construite quand tu va vouloir en changer la metaclasse.
Accessoirement, et sis ce n'est pas indiscret, pourquoi veux-tu une
autre metaclasse pour les fonctions?
Non, ce n'est pas indiscret.
J'utilise ce principe pour appliquer la programmation par contrat :
pré-conditions, post-conditions et invariants de méthodes ou de classes.
Je sais, ça existe déjà (pycontract qui utilise __getattr__) mais
les exceptions ne sont pas très parlantes et on est obligé de spécifier
tous les modules que l'on veut traiter. Bref j'ai voulu faire qqchose
à ma sauce à base de métaclasses et ça marche très bien.
Par exemple :
class Test:
"""
inv:
self.j >0
"""
__metaclass__ = MetaContract
j = 1
k = None
def __init__(self):
"""
post:
len(self.k)==3
"""
self.k = [1,2,3]
def test(self, f=array(()),i=1, toto=1):
"""
This is a test function
pre:
isinstance(i, int)
isinstance(f,type(array(())))
post:
__return__ == 1
self.i == 1
len(f)==3
inv:
self.j == 1
isinstance(self.j,int)
"""
self.i = 1
self.j = 1
return 1
m = Test()
m.test(array((1,2,3)), i=1.0)
donne --->
Traceback (most recent call last):
File "../etc/metacontract.py", line 228, in ?
main()
File "../etc/metacontract.py", line 217, in main
m.test(array((1,2,3)), i=1.0)
File "../etc/metacontract.py", line 107, in _trace
raise ValueError(condition+' condition assertion
('+class_or_method+' contract line %d): %s'%(i, code_line,))
ValueError: Pre- condition assertion (method contract line 2):
isinstance(i, int)
Le problème est que je ne peux pas appliquer ce principe aux fonctions...
class Test:
class Test(object):
Si tu veux jouer avec les metaclasses, descripteurs et autres
joyeusetés, utilise les classes new-style (et sinon, pareil - les
classes old-styles n'existent plus guère que pour des raisins hystériques)
pardonne mon ignorance, mais j'ai peur de ne pas comprendre... quel est le "new-style" ?
Si oui, pour les fonctions, il te suffit d'ajouter explicitement les
décorateurs,ie:
@with_contract
def my_func(toto, tutu):
"""
pre:
isinstance(toto, int)
"""
# code here
oui, c'est vrai, mais dans ce cas, je suis obligé de modifier tous les modules
Sinon (je veux dire, si tu ne gères pas ça avec des décorateurs), c'est
que tu utilise __getattribute__, ce qui est une mauvaise idée AMHA.
Mes deux centimes...
class Test:
class Test(object):
Si tu veux jouer avec les metaclasses, descripteurs et autres
joyeusetés, utilise les classes new-style (et sinon, pareil - les
classes old-styles n'existent plus guère que pour des raisins hystériques)
pardonne mon ignorance, mais j'ai peur de ne pas comprendre... quel est le "new-style" ?
Si oui, pour les fonctions, il te suffit d'ajouter explicitement les
décorateurs,ie:
@with_contract
def my_func(toto, tutu):
"""
pre:
isinstance(toto, int)
"""
# code here
oui, c'est vrai, mais dans ce cas, je suis obligé de modifier tous les modules
Sinon (je veux dire, si tu ne gères pas ça avec des décorateurs), c'est
que tu utilise __getattribute__, ce qui est une mauvaise idée AMHA.
Mes deux centimes...
class Test:
class Test(object):
Si tu veux jouer avec les metaclasses, descripteurs et autres
joyeusetés, utilise les classes new-style (et sinon, pareil - les
classes old-styles n'existent plus guère que pour des raisins hystériques)
pardonne mon ignorance, mais j'ai peur de ne pas comprendre... quel est le "new-style" ?
Si oui, pour les fonctions, il te suffit d'ajouter explicitement les
décorateurs,ie:
@with_contract
def my_func(toto, tutu):
"""
pre:
isinstance(toto, int)
"""
# code here
oui, c'est vrai, mais dans ce cas, je suis obligé de modifier tous les modules
Sinon (je veux dire, si tu ne gères pas ça avec des décorateurs), c'est
que tu utilise __getattribute__, ce qui est une mauvaise idée AMHA.
Mes deux centimes...
class Test:
class Test(object):
Si tu veux jouer avec les metaclasses, descripteurs et autres
joyeusetés, utilise les classes new-style (et sinon, pareil - les
classes old-styles n'existent plus guère que pour des raisins
hystériques)
pardonne mon ignorance, mais j'ai peur de ne pas comprendre... quel est
le "new-style" ?
Si oui, pour les fonctions, il te suffit d'ajouter explicitement les
décorateurs,ie:
@with_contract
def my_func(toto, tutu):
"""
pre:
isinstance(toto, int)
"""
# code here
oui, c'est vrai, mais dans ce cas, je suis obligé de modifier tous les
modules
que je veux "tracer" ce que justement je voulais éviter.
Une autre solution serait, lors de l'import de chaque module, de faire
qqchose
du type :
module.my_func = decorate(module.my_func)
class Test:
class Test(object):
Si tu veux jouer avec les metaclasses, descripteurs et autres
joyeusetés, utilise les classes new-style (et sinon, pareil - les
classes old-styles n'existent plus guère que pour des raisins
hystériques)
pardonne mon ignorance, mais j'ai peur de ne pas comprendre... quel est
le "new-style" ?
Si oui, pour les fonctions, il te suffit d'ajouter explicitement les
décorateurs,ie:
@with_contract
def my_func(toto, tutu):
"""
pre:
isinstance(toto, int)
"""
# code here
oui, c'est vrai, mais dans ce cas, je suis obligé de modifier tous les
modules
que je veux "tracer" ce que justement je voulais éviter.
Une autre solution serait, lors de l'import de chaque module, de faire
qqchose
du type :
module.my_func = decorate(module.my_func)
class Test:
class Test(object):
Si tu veux jouer avec les metaclasses, descripteurs et autres
joyeusetés, utilise les classes new-style (et sinon, pareil - les
classes old-styles n'existent plus guère que pour des raisins
hystériques)
pardonne mon ignorance, mais j'ai peur de ne pas comprendre... quel est
le "new-style" ?
Si oui, pour les fonctions, il te suffit d'ajouter explicitement les
décorateurs,ie:
@with_contract
def my_func(toto, tutu):
"""
pre:
isinstance(toto, int)
"""
# code here
oui, c'est vrai, mais dans ce cas, je suis obligé de modifier tous les
modules
que je veux "tracer" ce que justement je voulais éviter.
Une autre solution serait, lors de l'import de chaque module, de faire
qqchose
du type :
module.my_func = decorate(module.my_func)