【问题标题】:Defining a Method from A String in Python 3 and Referencing As Method在 Python 3 中从字符串定义方法并引用为方法
【发布时间】:2018-07-19 13:42:35
【问题描述】:

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

我希望该函数能够像任何其他方法一样运行。那是

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

【问题讨论】:

  • 如果您希望它的描述符协议工作并在实例上调用时绑定实例,请在类上设置函数。所以一个解决方案就是让你的 set_process 成为一个类方法。

标签: python python-3.x python-exec


【解决方案1】:

在上面@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

【讨论】:

    【解决方案2】:

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

    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)
    

    【讨论】:

    • 这实际上是如何工作的? types.MethodType() 是否创建了一个 MethodType 类型的对象以某种方式处理 self 问题?
    猜你喜欢
    • 1970-01-01
    • 2012-09-15
    • 2015-01-29
    • 2014-04-21
    • 2011-11-26
    相关资源
    最近更新 更多