0

我需要允许用户定义一个处理对象中数据的函数(其中的智慧和安全含义已经在另一个问题中详细讨论过,这里只是重复的评论。)

我希望该功能像任何其他方法一样起作用。那是

def my_method(self):...

将被调用:

obj_handle.my_method()

我几乎在下面实现了这一点,只是需要将结果函数self作为参数显式传递,而不是像方法典型的那样将其作为第一个参数接收。

p你可以在我有奇怪self.process(self)电话的属性中看到这一点。

我想我需要提供一些东西exec,比如globals()字典,但我不确定几件事:

  1. 这个对吗?
  2. 什么是globals()类中的等价物?
  3. 这能解决问题吗?如果不是,我需要做什么?

所以问题是,如何让exec()定义的函数充当对象的方法?

class test:
   def __init__(self, a, b):
       self.a=a
       self.b=b

   @property
   def p(self):
       return self.process(self)

   def set_process(self,program):
       func_dict={}
       proc_fun = exec(program,func_dict)
       setattr(self,'process',func_dict['process'])

   def process(self):
       return self.a+self.b

t=test(1,2)
prog = '''\
def process(self):
    return self.a * self.b
'''

t.set_process(prog)
t.p
4

2 回答 2

2

在上面@juanpa.arrivillaga 的评论中回答:

如果您希望其描述符协议工作并在实例上调用时绑定实例,请在类上设置该函数。所以一个解决方案只是让你的 set_process 成为一个类方法。– juanpa.arrivillaga 1 小时前

工作成果

class test:
    def __init__(self, a, b):
        self.a=a
        self.b=b

    @property
    def p(self):
        return self.process()

    @classmethod
    def set_process(cls,program):
        func_dict={}
        proc_fun = exec(program,func_dict)
        setattr(cls,'process',func_dict['process'])

    def process(self):
        return self.a+self.b

t=test(1,2)
prog = '''\
def process(self):
    return self.a * self.b
'''

test.set_process(prog)
t.p
于 2018-07-19T17:10:52.930 回答
1

如果要对实例而不是类进行操作:

import types

class Test:

    def __init__(self, a, b):
        self.a = a
        self.b = b

    @property
    def p(self):
        return self.process()

    def set_process(self, program):
        d = dict()
        exec(program, d)
        self.process = types.MethodType(d["process"], self)

    def process(self):
        return self.a + self.b

prog = '''\
def process(self):
    return self.a * self.b
'''

t = Test(1, 2)
t.set_process(prog)
print(t.p)

t = Test(1, 2)
print(t.p)
于 2018-07-19T17:27:34.603 回答