1

我有一个类通过用户指定的函数转换一些值。对函数的引用在构造函数中传递并保存为属性。我希望能够腌制或复制课程。在__ 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' object is not callable, 正如预期的那样。

4

2 回答 2

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'

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

如果要在当前范围内搜索,可以执行以下操作(从此处扩展):

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是一个 attr this)。

于 2013-05-11T05:16:25.333 回答
1

我想如果你问同样的问题,我来这里是为了。

答案是简单地使用 eval() 来评估名称。

>>> ref = eval('name')

这将在执行 eval 的范围内返回“name”引用的内容,然后您可以确定该引用是否是函数。

于 2020-10-04T13:28:25.780 回答