Bengt Richter wrote: [...]
Please pretend things worked the way you want, and post an example. Maybe
we can make it work.
Regards,
Bengt Richter
Ok , the complete use case is :
def fun1(a,b,obj = None):
isSuplied = 1
if not obj :
obj = generateObject()
isSuplied = 0
<do something with obj>
if not isSuplied : obj.dispose()
def fun2(c,obj = None):
isSuplied = 1
if not obj :
obj = generateObject()
isSuplied = 0
<do something else with obj>
if not isSuplied : obj.dispose()
So , maybe i will need to define fun3 later,i dont know , but fun3 also will
work with "obj".
So the thing is to try to factorize the code,so that it is in the decorator:
def dec(func):
def wrapper(*arg,**kw):
obj = kw.get('obj',None)
isSuplied = 1
if not obj :
obj = generateObject()
kw['obj'] = obj
isSuplied = 0
res = func(*arg,**kw)
if not isSuplied : obj.dispose()
return res
return wrapper
so the previous function declarations, will look like:
@dec
def fun1(a,b,obj = None):
<do something with obj>
@dec
def fun2(c,obj = None):
<do something with obj>
but i have to define obj = None in each function,but the functions should
know they will have an obj instance available, so the byte code hack would
be :
def dec(func):
def wrapper(*arg,**kw):
obj = kw.get('obj',None)
isSuplied = 1
if not obj :
obj = generateObject()
isSuplied = 0
<< BIND OBJ TO THE FUNCTION LOCAL NAMESPACE >>
res = func(*arg,**kw)
if not isSuplied : obj.dispose()
return res
return wrapper
so the functions knowing they will be altered(added an instance of obj),they
will just need to define their own arguments only.
@dec
fun1(a,b) : obj.result = a + b
@dec
fun2(c) : obj.result = c * 4
So the duplication would be removed.
But i realized the best aproach,is a callable class that provides that
infrastructure, or not? =P
Maybe this implements what you are asking for?
----< vegetax.py >-------------------------
from ut.presets import presets
class generateObject(object):
def dispose(self): print 'disposing of %r: %r' %(self, vars(self))
def dec(func):
def getfun(f): return func # fake decorator to pass func to presets
def wrapper(*arg,**kw):
obj = kw.get('obj',None)
isSuplied = 1
if not obj :
obj = generateObject()
isSuplied = 0
else:
del kw['obj'] # don't pass unexpected kwarg to func
#<< BIND OBJ TO THE FUNCTION LOCAL NAMESPACE >>
@presets(obj=obj) # per comment above
@getfun
def funcalias(): pass # just for a local name to bind
res = funcalias(*arg, **kw)
if not isSuplied : obj.dispose()
return res
return wrapper
#so the functions knowing they will be altered(added an instance of obj),they
#will just need to define their own arguments only.
if __name__ == '__main__':
@dec
def fun1(a,b) : obj.result = a + b; return obj, vars(obj)
@dec
def fun2(c) : obj.result = c * 4; return obj, vars(obj)
o, v = fun1(111, 222) # bind obj to show that new obj is generated on next call
print o, v
print fun2(1111)
print 'supplying obj to fun2:', fun2(2222, obj=generateObject()) # supplied
print 'both ways:', (fun2(1111), fun2(2222, obj=generateObject()))
-------------------------------------------
[22:21] C:\pywk\clp>py24 vegetax.py
disposing of <__main__.generateObject object at 0x02EF9F0C>: {'result': 333}
<__main__.generateObject object at 0x02EF9F0C> {'result': 333}
disposing of <__main__.generateObject object at 0x02EF33CC>: {'result': 4444}
(<__main__.generateObject object at 0x02EF33CC>, {'result': 4444})
supplying obj to fun2: (<__main__.generateObject object at 0x02EF33CC>, {'result': 8888})
both ways: disposing of <__main__.generateObject object at 0x02EF33CC>: {'result': 4444}
((<__main__.generateObject object at 0x02EF33CC>, {'result': 4444}), (<__main__.generateObject o
bject at 0x02EF316C>, {'result': 8888}))
Regards,
Bengt Richter