OVH Cloud OVH Cloud

Pbm avec quelque notion de python.

1 réponse
Avatar
DAIREAUX Jean-Baptiste
Bonjour, j'essai de construire un décorateur qui déplace l'evaluation d'une

fonction au moment où sont résultat est nécéssaire.

par exemple :

@lazy

def f(x) :

print "execution de fn"

return x+2

a=f(5) #n'affiche rien

b=a+2 # affiche execution de fn et b vaut alors 9

je suis en partie arriver au résultat voulu. (CF module join)

Mon probleme est l'application d'un methode retardé d'un objet . (Cf le

dernier test du module.)

Je ne récupere pas l'argument qui doit étre passé à self.

Quelq'un aurai une solution ?

J.B.D.


------------------------
lazy.py
# -*- coding: cp1252 -*-
import sys

TRACE=True #affiche ou pas des info de traçage

if TRACE :
def iprint(st):
print(st)
else :
def iprint(st):
pass

def run(k,uv):
u=uv[0]
v=uv[1]
st=["u["+str(x)+"]" for x in xrange(len(u))]
st2=[ str(sk)+"="+repr(sv) for sk,sv in v.iteritems() ]
s=",".join(st+st2)
sf="lambda(z): k("+s+")"
dic1=globals().copy()
dic1.update({'k':k ,'u':u,'v':v})
f=eval(sf,dic1,None)
return f('&')

def wait(k,*a,**b):
yield run(k,[a,b])

###############################
#Gen ne sert pas. Ce fut une fonction ou j'ai cherché des solutions a
diverse pbm
def gen(k):
a=k.func_code.co_argcount
if k.func_code.co_flags & 0x04 :
b=a+1
else :
b=a
if k.func_code.co_flags & 0x08 :
c=b+1
else :
c=b
print "nb argument : "+str(a)
print "nom des argument : "+str(k.func_code.co_varnames[0:a])
####################################"


class continuation(object):
"""
Une instance de continuation est crée par l'appel a la fonction décorer
par @lazy
l'objet attend une quelconque utilisation pour s'évaluer et renvoyer la
réponse adéquate.
"""
st=["_oo_","_calc_","_resu_"]
def __init__(self,o):
#self._oo_=o
object.__setattr__(self,'_oo_',o)
#self._calc_=False
object.__setattr__(self,'_calc_',False)
#self._resu_=None
object.__setattr__(self,'_resu_',None)

def _calcule(self) :
if not self._calc_ :
iprint("Calcule de la valeur")
a=self._oo_.next()
#self._resu_=a
object.__setattr__(self,'_resu_',a)
#self._calc_=True
object.__setattr__(self,'_calc_',True)
iprint( "fin calcule valeur")

def __repr__(self):
iprint( "repr")
self._calcule()
return repr(self._resu_)

def __getattr__(self,name):
iprint ("getattr : "+str(name))
self._calcule()
st="lambda (u): u."+name
#a=eval(st,globals(),locals())
a=eval(st,None,None)
return a(self._resu_)

def __setattr__( self, name, value) :
#if name in continuation.st :
# object.__setattr__(self, name, value)
#else :
iprint( "setattr : "+str(name)+"="+str(value))
self._calcule()
self._resu_.__setattr__(name, value)

def __nonzero__(self):
iprint ("nonzero")
self._calcule()
return self._resu_.__nonzero__()

def __call__(self,*a,**b) :
iprint( "call")
self._calcule()
return run(self._resu_,[a,b])

def __str__(self) :
iprint( "str")
self._calcule()
return str(self._resu_)

def __lt__( self, other) :
iprint ("<")
self._calcule()
return self._resu_<other

def __le__( self, other) :
iprint ("<=")
self._calcule()
return self._resu_<=other

def __eq__( self, other) :
iprint ("==")
self._calcule()
return self._resu_==other

def __ne__( self, other) :
iprint ("!= ou <>")
self._calcule()
return self._resu_!=other

def __gt__( self, other) :
iprint (">")
self._calcule()
return self._resu_>other

def __ge__( self, other) :
iprint (">=")
self._calcule()
return self._resu_>=other

def __hash__( self) :
iprint ("hash")
self._calcule()
return self._resu_.__hash__()

def __unicode__( self) :
iprint ("unicode")
self._calcule()
return self._resu_.__unicode__()

def __iter__( self ) :
iprint ("iter")
self._calcule()
return self._resu_.__iter__()

def __getitem__( self, key) :
iprint ("getitem "+str(key))
self._calcule()
return self._resu_[key]

def __setitem__( self, key, value) :
iprint ("setitem")
self._calcule()
self._resu_[key]=value

def __delitem__( self, key) :
iprint ("delitem")
self._calcule()
self._resu_.__delitem__(key)

def __contains__( self, item) :
iprint ("contains")
self._calcule()
return self._resu_.__contains__(item)

def __len__(self) :
iprint ("len")
self._calcule()
return self._resu_.__len__()

if sys.version_info < (2, 0):
# They won't be defined if version is at least 2.0 final
def __getslice__(self, i, j):
iprint ("getslice")
self._calcule()
return self._resu_.__getslice__(i,j)

def __setslice__(self, i, j, seq):
iprint ("setslice")
self._calcule()
self._resu_.__setslice__(i,j,seq)

def __delslice__(self, i, j):
iprint ("delslice")
self._calcule()
self._resu_.__delslice__(i,j,seq)

def __add__( self, other) :
iprint ("add")
self._calcule()
return self._resu_ + other

def __sub__( self, other) :
iprint ("sub")
self._calcule()
return self._resu_ - other

def __mul__( self, other) :
iprint ("mul")
self._calcule()
return self._resu_ * other

def __floordiv__( self, other) :
iprint ("floordiv")
self._calcule()
return self._resu_ // other

def __mod__( self, other) :
iprint ("mod")
self._calcule()
return self._resu_ % other

def __divmod__( self, other) :
iprint ("divmod")
self._calcule()
return divmod(self._resu_ , other)

def __pow__( self, other, modulo=None) :
iprint ("pow")
self._calcule()
return pow(self._resu_ , other ,modulo)

def __lshift__( self, other) :
iprint ("lshift")
self._calcule()
return self._resu_ << other

def __rshift__( self, other) :
iprint ("rshift")
self._calcule()
return self._resu_ >> other

def __and__( self, other) :
iprint ("and")
self._calcule()
return self._resu_ & other

def __xor__( self, other) :
iprint ("xor")
self._calcule()
return self._resu_ ^ other

def __or__( self, other) :
iprint ("or")
self._calcule()
return self._resu_ | other

def __div__( self, other) :
iprint ("div")
self._calcule()
return self._resu_ / other

def __truediv__( self, other) :
iprint ("truediv")
self._calcule()
return self._resu_ / other

def __radd__( self, other) :
iprint("radd")
self._calcule()
return other + self._resu_

def __rsub__( self, other) :
iprint ("rsub")
self._calcule()
return other - self._resu_

def __rmul__( self, other) :
iprint ("rmul")
self._calcule()
return other * self._resu_

def __rdiv__( self, other) :
iprint ("rdiv")
self._calcule()
return other / self._resu_

def __rtruediv__( self, other) :
iprint ("rtruediv")
self._calcule()
return other / self._resu_

def __rfloordiv__( self, other) :
iprint( "rfloordiv")
self._calcule()
return other // self._resu_

def __rmod__( self, other) :
iprint ("rmod")
self._calcule()
return other % self._resu_

def __rdivmod__( self, other) :
iprint ("rdivmod")
self._calcule()
return divmod(other , self._resu_)

def __rpow__( self, other) :
iprint ("rpow")
self._calcule()
return other ** self._resu_

def __rlshift__( self, other) :
iprint ("rlshift")
self._calcule()
return other << self._resu_

def __rrshift__( self, other) :
iprint ("rrshift")
self._calcule()
return other >> self._resu_

def __rand__( self, other) :
iprint ("rand")
self._calcule()
return other & self._resu_

def __rxor__( self, other) :
iprint ("rxor")
self._calcule()
return other ^ self._resu_

def __ror__( self, other) :
iprint ("ror")
self._calcule()
return other | self._resu_

def __iadd__( self, other) :
iprint ("iadd")
self._calcule()
a=self._resu_
a+= other
return a

def __isub__( self, other) :
iprint ("isub")
self._calcule()
a=self._resu_
a-= other
return a

def __imul__( self, other) :
iprint ("imul")
self._calcule()
a=self._resu_
a*= other
return a

def __idiv__( self, other) :
iprint ("idiv")
self._calcule()
a=self._resu_
a/= other
return a

def __itruediv__( self, other) :
iprint ("itruediv")
self._calcule()
a=self._resu_
a/= other
return a

def __ifloordiv__( self, other) :
iprint ("ifloordiv")
self._calcule()
a=self._resu_
a//= other
return a

def __imod__( self, other) :
iprint ("imod")
self._calcule()
a=self._resu_
a%= other
return a

def __ipow__( self, other, modulo=None) :
iprint ("ipow")
self._calcule()
a=self._resu_
a**= other
return a

def __ilshift__( self, other) :
iprint ("ilshift")
self._calcule()
a=self._resu_
a<<= other
return a

def __irshift__( self, other) :
iprint ("irshift")
self._calcule()
a=self._resu_
a>>= other
return a

def __iand__( self, other) :
iprint ("iand")
self._calcule()
a=self._resu_
a&= other
return a

def __ixor__( self, other) :
iprint ("ixor")
self._calcule()
a=self._resu_
a^= other
return a

def __ior__( self, other) :
iprint ("ior")
self._calcule()
a=self._resu_
a|= other
return a

def __neg__( self) :
iprint ("neg")
self._calcule()
return - self._resu_

def __pos__( self) :
iprint ("pos")
self._calcule()
return + self._resu_

def __abs__( self) :
iprint ("abs")
self._calcule()
return abs( self._resu_ )

def __invert__( self) :
iprint ("invert")
self._calcule()
return ~ self._resu_

def __complex__( self) :
iprint ("complex")
self._calcule()
return complex( self._resu_)

def __int__( self) :
iprint ("int")
self._calcule()
return int(self._resu_)

def __long__( self) :
iprint ("long")
self._calcule()
return long(self._resu_)

def __float__( self) :
iprint ("float")
self._calcule()
return float(self._resu_)

def __oct__( self) :
iprint ("oct")
self._calcule()
return oct(self._resu_)

def __hex__( self) :
iprint ("hex")
self._calcule()
return hex(self._resu_)

def __coerce__( self, other) :
iprint ("coerce")
self._calcule()
return coerce(self._resu_,other)

class lazy(object):
"""
lazy est le décorateur qui retarde l'execution des fonction.
"""
def __init__(self,k) :
self.k=k

def __call__(self,*a,**b) :
iprint ("appel de la lazy fonction")
return continuation(wait(self.k,*a,**b))

def __getattr__(self,name):
iprint ("lazy.getattr : "+str(name))
st="lambda (u): u."+name
#a=eval(st,globals(),locals())
a=eval(st,None,None)
return a(self.k)

#Exemple de test :

class toto(object) :
def __init__(self,a):
self.v=a

def getv(self):
return self.a

def getaddval(self,t,y):
iprint("traitement de getaddval("+str(t)+","+str(y)+")")
return self.v + t + y

getaddval=lazy(getaddval)

@lazy
def donne_toto(y) :
iprint("execution de donne_toto")
return toto(y)


@lazy
def fn(x,y,larg=None):
r=x*2
print "execution de fn("+str(x)+","+str(y)+","+str(larg)+") --> "+str(r)
return r

@lazy
def f():
print "execution de f"
return complex(5,8)

@lazy
def f2() :
print "execution de f2"
return [1,2,3]

def nonlazy():
print "execution de non lazy"
return 2

print "fin de la déclaration des éléments du test"

d=fn(nonlazy(),'g')
print "d est affecté"
u=f()
print "u est affecté"
print "u="+str(u)
print "d="+str(d)

print "fin test 1"

gen(fn)
print "fin test 2"

t=toto(5) #fonction bien au print
#t=donne_toto(5) #ne fonction pas au print
print "t est affecté"
print str(t.getaddval(1,2))#pbm
print "fin test 3"

1 réponse

Avatar
DAIREAUX Jean-Baptiste
...
Je ne récupere pas l'argument qui doit étre passé à self.

Quelq'un aurai une solution ?

J.B.D.

...


J'ai la solution à mon pbm :

lors de la déclaration d'une classe ( class c(truc): ) les méthodes sont
d'abord évaluées en tant que fonction puis transformées en méthodes lors de
la fin de la déclaration de la classe.

exemple :
class t :
def fn (self) :
pass
#ici fn est une fonction non pas une méthode appartenant à la classe

#ici fn est devenue une méthode de la classe

le probleme que j'avais était que le système qui transforme une fonction en
méthode ne sait pas gérer les 'call object'

Donc si on doit décorer une méthode il faut obligatoirement que le
décorateur renvoie une fonction et non un objet appelable.

J.B.D.