1

I have some class which take a function as on of its init arguments:

class A(object):

    def __init__(self, some_var, some_function):
        self.some_function = some_function
        self.x = self.some_function(some_var) 

I can create a function, pass it to an instance of the object, and save it using pickle:

import pickle as pcl

def some_function(x):
    return x*x

a = A(some_var=2, some_function=some_function)

pcl.dump(a, open('a_obj.p', 'wb')) 

Now I want to open this object in some other code. However, I don't want to include the def some_function(x): code in each file which uses this specific saved object.

So, what's the best python practice to pass external function as an argument to a python object and then save the object, such that the external function is "implemented" inside the object instance, so it doesn't have to be written in every file which uses the saved object?

Edit: Let me clarify, I don't want to save the function. I want to save only the object. I there's any elegant way to "combine" the external function inside the object so I can pass it as an argument and then it "becomes" part of this object's instance?

mangate
  • 648
  • 1
  • 5
  • 17
  • I don't think you can pickle a function. Even if there is a way, anytime you wanted to update the code you'd have to find all the places it's saved. Why not create a module with your function then install that on any system you want to use your object on? – Cfreak Mar 25 '17 at 19:19
  • We though about this solution but we try to avoid this at this point – mangate Mar 25 '17 at 19:28

2 Answers2

1

The easiest way to do what you are asking is with the dill module.

You can dump an instance of an object like this:

import dill

def f(x):
    return x*x

class A(object):
    def __init__(self, some_var, some_function):
        self.some_function = some_function
        self.x = self.some_function(some_var)

a = A(2, f)

a.x
# returns:
# 4

with open('a.dill', 'wb') as fp:
    dill.dump(a, fp)

Then create a new instance of python, you can load it back in using:

import dill

with open('a.dill', 'rb') as fp:
    a = dill.load(fp)

a.x
# returns:
# 4

a.some_function(4)
# returns:
# 16
James
  • 32,991
  • 4
  • 47
  • 70
0

If you really, really wanted to do this it would be possible with the Marshal module, from which Pickle is based on. Pickling functions is intentionally not possible for security reasons.

There is also a lot of info you would probably find useful in this question: Is there an easy way to pickle a python function (or otherwise serialize its code)?

Community
  • 1
  • 1
Julien
  • 5,243
  • 4
  • 34
  • 35
  • Edited now. I don't want to save the function . – mangate Mar 25 '17 at 19:26
  • If you don't want to save the function, your question constraint is a contradiction. The origin of the reference to the function you want has to be *somewhere* if you are to load it from disk! – Julien Mar 25 '17 at 19:28