我有一个通过用户指定的函数转换某些值的类。对函数的引用在构造函数中传递并保存为属性。我希望能够腌制或复制课程。在 __ getstate __ ()方法中,我将字典条目转换为字符串,以使其可以安全地进行酸洗或复制。但是,在 __ setstate __ ()方法中,我想从字符串转换回函数引用,因此新类可以转换值。
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()
输出:array([1.,2.71828183])
new_transformer = deepcopy(my_transformer)
new_transformer.transform()
这给了我:TypeError:'str'对象不能按预期调用。
答案 0 :(得分: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(可能是递归的,但请注意this
是this
的attr。)
答案 1 :(得分:0)
我想,如果您在问同样的问题,我来这里的是
答案只是使用eval()来评估名称。
>>> ref = eval('name')
这将返回eval所在范围内的“名称”引用 执行,则可以确定引用是否为函数。