Dobry den,
mam dekorator @cache(size=xxx), chtel bych jeho hodnotu nastavovat az podle parametru tridy ve ktere je pouzit, ale nedari se mi pristoupt k ani jednomu z instance, class, static, global promennych. Asi lepsi ukazka kyzeneho stavu v (pseudo) pythonu:
# dekorator
def cache(f):
...
class A():
def __init__(self, cacheSize=0):
self.cacheSize = cacheSize
@cache(maxsize=self.cacheSize) # tohle nejde..hledal jsem vsemozne pristupy
def long_method(self,x):
...
# pouziti
a=A(5)
a.long_method(3)
dekuji moc za vysvetleni!
Ten dekorator je executovany pri vytvoreni classy a vtedy self neexistuje, self vznika pri vytvoreni instancie. Co mozes urobit je v inner funkcii ten parameter vytiahnut z funkcie long_method kedze ta pasne dekoratoru aj svoj self.
Zdravím,
Toto jde udělat vcelku jednoduše:
from functools import wraps
def cache(f):
print "Dekoruji."
@wraps(f)
def decorated_func(self, *args, **kwargs):
print self # tady je možné dělat se self cokoliv
return f(self, *args, **kwargs)
return decorated_func
Dekuji za odpovedi,
muj problem je, ze to co chci wrappnout, abych mohl predat self.xxx parametr neni moje funkce, ale uz dekorator, ktery vyzaduje jeden argument.
tedy:
# orig wrapper, ktery nemuzu menit (c++ binding), pouziva se takto:
@origcache(maxsize=3)
def long_foo(n):
pass
# muj cil: vytvorit @mycache ktery precte self.cacheSize z contextu sve instance?
# a bude pritom volat @origcache
class A():
def __init__(cacheSize):
self.cacheSize = cacheSize
@mycache
def long_foo(n):
pass
Z Vasich odpovedi chapu proc to nefunguje, ale neumim si priohnout @wraps tak, aby mi opravovalo dekorator. Nasel jsem neco o dekoratorech/descriptorech ...ale v tom se uprimne moc nevyznam.
Diky
Koukni se na https://wiki.python.org/moin/PythonDecoratorLibrary (https://wiki.python.org/moin/PythonDecoratorLibrary)
Je tam Memoize. To je velice podobné tomu co chceš.
Memoize znam, to je pouze implementace cache, tu uz mam. Me jde o to, jak dekoratoru predat argument ze self.neco
?
def origcache(f,size=3):
def g(*args,**kwds):
#print(*args, **kwds)
print('Calling decorated function',size)
return f(*args, **kwds)
return g
metaCache={}
def cache(f):
def g(*args,**kwds):
try:
return metaCache[(f,args[0])](*args[1:],**kwds)
except KeyError:
print("defining")
newf=origcache(f,size=args[0].s)
metaCache[(f,args[0])]=newf
return newf(*args[1:],**kwds)
else:
return
return g
class A():
def __init__(self):
self.s=5
@cache
def f(x):
return str(x)+"aa"
a=A()
print(a.f(2))
print(a.f(2))
Zkus to bez cache!