Reputation: 2441
I have two functions:
library function which I cannot change say lib_func( func, param1)
i.e. lib_func
takes a function func
and some other parameter param1
as arguments.
user defined function user_func
.
For example:
x = 0
y = 0
def user_func():
global x
global y
return sqrt(x*y)
Now the problem is I want to pass x to user_func
as argument not as globals while passing user_func
to lib_func
.
Upvotes: 3
Views: 1343
Reputation: 152637
A function is simply an object that can be called so defining a class with a __call__
method is in principle equivalent to defining a function. At least in the context you are giving.
So:
def user_func(x, y, z):
return anything_with(x, y, z)
is equivalent to:
class user_class(object):
@staticmethod # staticmethod so that it can be called on the class
def __call__(x, y, z):
return anything_with(x, y, z)
as it stands this is just obfuscation. But the magic happens when you create an instance with predefined attributes and you only specifiy the variable arguments as parameters for the call
:
class user_class(object):
def __init__(self, x):
self.x = x
def __call__(self, y, z): # No x as parameter!
return do_anything_with(self.x, y, z) # use the predefined x here
but you need to alter the way you call lib_func
then:
x = 0
user_class_instance = user_class(0)
result = lib_func(user_class_instance, param1)
So it will repeat to call the instance with different y
and z
but x
will be kept constant
Most of such lib_func
functions however allow passing variable parameters (such that will be given to the user_func
), for example scipy.optimize.curve_fit
:
curve_fit(user_func, x, y, [initial_guess_param1, param2, ...])
there user_func
will be called by curve_fit
internally (you don't have to do anything!) like:
user_func(x, initial_guess_param1, param2, ...)
# Then curve-fit modifies initial_guess_param1, param2, ... and calls it again
user_func(x, initial_guess_param1, param2, ...)
# and again modifies these and calls again
user_func(x, initial_guess_param1, param2, ...)
# ... until it finds a solution
there x
and y
are defined and not changed when calling curve_fit
but initial_guess_param1
will be changed while finding the optimal curve_fit
.
Upvotes: 3
Reputation: 137
try to wrap the user_func
and return a new function for lib_func
:
def wrapuserfunc(x):
user_func.x = x
return user_func
def user_func():
if hasattr(user_func, 'x'):
print user_func.x
lib_func(wrapuserfunc(1), param1) # user_func.x = 1
# get x in user_func
print user_func.x # x = 1
wrapuserfunc(x)
works fine.
Function is object in Python.
Upvotes: -2
Reputation: 39546
If I understood task correctly, you'll need two things:
create new function to wrap user_func
with x, y
params
use functools.partial to get one more function with passed params
Here's example.
Module user_module.py
where user_func
defined:
x = 0
y = 0
def user_func():
global x
global y
print('user_func', x, y)
Module main.py
where you need job done:
def lib_func(func, param1):
print('lib_func', param1)
func()
# Create user_func with params:
import user_module
def new_user_func(x, y):
user_module.x = x
user_module.y = y
user_module.user_func()
# Use functools.partial to create user_func with ready params:
from functools import partial
f = partial(new_user_func, 1, 2)
lib_func(f, 'param1')
f = partial(new_user_func, 3, 4)
lib_func(f, 'param1')
Output for this example:
lib_func param1
user_func 1 2
lib_func param1
user_func 3 4
Upvotes: 1
Reputation: 21831
You can wrap your user_func()
with another function
def parameterized_func(local_x):
global x
x = local_x
return user_func()
And then pass the new parameterized_func()
function to your lib_func()
.
This is not very nice, and will obviously change the global x
variable.
I would suggest looking into and see if you can't change the user_func()
function instead.
Upvotes: 1