2013-05-11 48 views
1

我有一个类可以通过用户指定的函数转换某些值。对函数的引用在构造函数中传递并保存为属性。我希望能够腌制或复制课程。在__ getstate __()方法中,我将字典条目转换为一个字符串,以使其可以安全地进行酸洗或复制。但是,在__ setstate __()方法我想从字符串转换回函数引用,所以新类可以转换值。如何将字符串转换为python中的函数引用

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? 

传递可以是任何函数,因此涉及与一组固定的功能的引用字典的解决方案是不实际的/柔性的足够的功能参考。我会像下面这样使用它。

from copy import deepcopy 
import numpy as np 

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

此输出:阵列([1,2.71828183])

new_transformer = deepcopy(my_transformer) 
new_transformer.transform() 

这使我:类型错误: 'STR' 对象不是可调用,如所预期。

回答

2

您可以使用dir来访问给定范围内的名称,然后使用getattr来检索它们。

例如,如果你知道这个功能是在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' 

这可以扩展在其他模块/范围看。

如果你想在当前范围内进行搜索,你可以做以下(从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.' 

要搜索子模块/导入的模块,你可以遍历基于类型的attrs(潜在的递归,不过请注意,thisthis的属性)。

+0

工程就像一个魅力。非常感谢。 – worldcitizen 2013-05-13 20:33:15

相关问题