1

I have a class that transforms some values via a user-specified function. The reference to the function is passed in the constructor and saved as an attribute. I want to be able to pickle or make copies of the class. In the __getstate__() method, I convert the dictionary entry to a string to make it safe for pickling or copying. However, in the __setstate__() method I'd like to convert back from string to function reference, so the new class can transform values.

class transformer(object):
    def __init__(self, values=[1], transform_fn=np.sum):
        self.values = deepcopy(values)
        self.transform_fn = transform_fn
    def transform(self):
        return self.transform_fn(self.values)
    def __getstate__(self):
        obj_dict = self.__dict__.copy()
        # convert function reference to string
        obj_dict['transform_fn'] = str(self.transform_fn)
        return obj_dict
    def __setstate__(self, obj_dict):
        self.__dict__.update(obj_dict)
        # how to convert back from string to function reference?

The function reference that is passed can be any function, so solutions involving a dictionary with a fixed set of function references is not practical/flexible enough. I would use it like the following.

from copy import deepcopy
import numpy as np

my_transformer = transformer(values=[0,1], transform_fn=np.exp)
my_transformer.transform()

This outputs: array([ 1. , 2.71828183])

new_transformer = deepcopy(my_transformer)
new_transformer.transform()

This gives me: TypeError: 'str' object is not callable, as expected.

2 Answers 2

2

You could use dir to access names in a given scope, and then getattr to retrieve them.

For example, if you know the function is in numpy:

import numpy

attrs = [x for x in dir(numpy) if '__' not in x] # I like to ignore private vars

if obj_dict['transform_fn'] in attrs:
    fn = getattr(numpy, obj_dict['transform_fn'])
else:
    print 'uhoh'

This could be extended to look in other modules / scopes.

If you want to search in the current scope, you can do the following (extended from here):

import sys

this = sys.modules[__name__]

attrs = dir(this)

if obj_dict['transform_fn'] in attrs:
    fn = getattr(this, obj_dict['transform_fn'])
else:
    print 'Damn, well that sucks.'

To search submodules / imported modules you could iterate over attrs based on type (potentially recursively, though note that this is an attr of this).

Sign up to request clarification or add additional context in comments.

Comments

2

I think if you are asking the same question, I came here for.

The answer is simply use eval() to evaluate the name.

>>> ref = eval('name')

This is going to return what 'name' references in the scope where the eval is executed, then you can determine if that references is a function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.