How to deep copy a function object

I am creating a function that returns the value indicated by a variable. how

y = 1. def f(x): return y 

I need this function as a function object to create another object

 dist = dist.distribution(f, other_variables) 

this works great. But if I want to create several different distribution objects (with different functions f in the sense that y is changing). how

 dist = dist.distribution(f, other_variables) y = 2. dist2 = dist.distribution(f, other_variables) 

Then, all distribution objects return only the last given value of y. I.e.

 dist.f()(1.) >>>> 2. dist2.f()(1.) >>>> 2. 

Instead of the expected

 dist.f()(1.) >>>> 12. dist2.f()(1.) >>>> 2. 

Obviously, the problem is that the function f accesses the variable only when it is called, and not initially.

Is there any way? In the end I want: A function with only one variable (x, although in this case it does nothing, it is needed by others), which returns the y value of the moment the distribution is created. Therefore, in principle, I want this function to be deeply copied when initializing the distribution, in the sense that it will no longer be affected by any change of variables. Is it possible?

+4
source share
1 answer

Do not use global variables for this. There is also no need for a β€œdeep” function; global y not part of the function state at all.

Use a factory function that provides a scope value, or use functools.partial() to provide a default argument to your function.

Factory function:

 def produce_f(y): def f(x): return y return f dist = dist.distribution(produce_f(1.), other_variables) 

Now y is the rolling value for f , produce_f() returns a new f each time it is called, and y saved as a cell variable for f .

Demo:

 >>> f1 = produce_f(12.) >>> f2 = produce_f(42.) >>> f1('foo') 12.0 >>> f2('foo') 42.0 

Using functools.partial() :

 from functools import partial def f(y, x): return y dist = dist.distribution(partial(f, 1.), other_variables) 

Here partial(f, 1.) creates a new callable that will call f(1., ...) whenever called, adding any additional arguments passed to.

Demo:

 >>> f1 = partial(f, 12.) >>> f2 = partial(f, 42.) >>> f1('foo') 12.0 >>> f2('foo') 42.0 
+6
source

All Articles