【问题标题】:How to add a dynamic method encoded in a string during class initialization?如何在类初始化期间添加以字符串编码的动态方法?
【发布时间】:2019-03-05 20:48:09
【问题描述】:

我正在为进化算法开发一个代理类。我需要向它添加一个方法,该方法是从从父级继承的字符串生成的。 这是一个最小的例子

class Agent:
    def __init__(self, s='\tif x > y:\n\t\treturn 1'):
        self.f_template = f'def f(self, x,y):\n{s}'

我希望方法self.f(self, x,y) 具有self.f_template 作为函数体。 我知道我可以稍后添加它:

A = Agent()
exec(A.f_template)
A.f = partial(f, A)

>>> A.f(3,2)
1

但是是否有可能在__init__() 期间而不是之后实现相同的目标?

只需执行以下操作即可提高 NameError: name 'f' is not defined

class Agent:
    def __init__(self, s='\tif x > y:\n\t\treturn 1'):
        self.f_template = f'def f(self, x,y):\n{s}'

        exec(self.f_template)
        self.f = partial(f, self)

【问题讨论】:

    标签: python methods dynamic


    【解决方案1】:

    这是因为 Python 编译器在确定哪些变量是局部变量时会查看代码块中的所有左值,在这种情况下,f 没有定义为 l-value,因此编译器在编译时会报错时间而不是运行时。这在 REPL 中不是问题,每行都是单独编译的。

    您可以改为使用locals() dict 来访问动态生成的变量名称:

    class Agent:
        def __init__(self, s='\tif x > y:\n\t\treturn 1'):
            self.f_template = f'def f(self, x,y):\n{s}'
            exec(self.f_template)
            self.f = partial(locals()['f'], self)
    

    【讨论】:

    • 非常感谢!
    猜你喜欢
    • 2023-03-26
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 2013-08-25
    • 2016-05-02
    • 1970-01-01
    • 2013-01-30
    • 2011-07-24
    相关资源
    最近更新 更多