There are two classes and I want to wrap item.foo
method only once, to prevent cache = {param1: 'param_value'}
being reinited
class Foo:
_count = 0
def foo(self, param2):
self._count += param2
class Bar:
_collection = [Foo(), Foo(), Foo()]
def bar(self, param1, param2):
for item in self._collection:
wrapped_function = wrapper(item.foo, param1)
wrapped_function(param2)
def wrapper(func, param1):
# some database call or whatever
cache = {param1: 'param_value'}
def _wrapper(*args, **kwargs):
# access value to read
print(cache[param1])
return func(*args, **kwargs)
return _wrapper
bar = Bar()
bar.bar(1, 2)
It can be achieved if wrapper
had no params in it and was used as a simple decorator, but I have to pass a param1
in it, though it's always the same.
I also can save cache = {param1: 'param_value'}
before the cycle in def bar
and pass it as the parameter, but I was wondering if there any other way to accomplish it.
Kinda can't wrap my head around it(pun intended)
It sounds like you want to wrap Foo.foo
, not item.foo
(which is different bound method for each value of foo
. Something like
class Bar:
_collection = [Foo(), Foo(), Foo()]
def bar(self, param1, param2):
wrapped_function = wrapper(Foo.foo, param1)
for item in self._collection:
wrapped_function(item, param2)
It's more complicated if you only want to apply the wrapper once per unique type of object in _collection
, as you need to build a cache of wrapped functions. Something like
class Bar:
_collection = [Foo(), Foo(), Foo()]
wrap_cache = {}
def bar(self, param1, param2):
for item in self._collection:
itype = type(item)
if itype.foo not in wrap_cache:
wrap_cache[itype] = wrapper(itype.foo, param1)
wrapped_function = wrap_cache[itype]
wrapped_function(param2)