python - 为什么当我要在 Python 中传递动态函数时遇到问题

标签 python python-3.x dynamic-code

我将动态地将函数传递给另一个类,如下所示

    class simulator(object):
        def __init__(self, fn_):

            print(self.test(fn_))


        def test(self, fn):
            return  fn(self, 20)


    class t(object):

        s = 'def get_fitness(x, y):\n return x+y'

        exec(s)

        def fnGetFitness(self,genes):
            return get_fitness(genes, 10)

        simulator(fnGetFitness)



    t()

但我遇到以下错误:

    File "N:/Job/GA/mine/dyn.py", line 25, in fnGetFitness
          return get_fitness(genes, 10)

    NameError: name 'get_fitness' is not defined

我猜它与范围有关,但我无法处理它 有人关注这个吗?

编辑:

这是一个更简单的代码,显示了问题:

    class t(object):
        def __init__(self):
            exec('def get_fitness(x, y):\n return x+y')
            print(get_fitness(2,3))
    t()

最佳答案

exec无关。您正在做的事情相当于(删除安全性):

class t(object):
    def get_fitness(x,y):
        return x+y

但是您的方法定义是在类级别,而不是在模拟器类上。

simulator(fnGetFitness)t 类上下文中调用 fnGetFitness,因此它不知道您的新函数。

这不起作用(get_fitness 也应该装饰为 @staticmethod 因为它没有 self 参数)

有效的方法是在全局级别动态定义(或不​​)函数,以便类可以调用它

s = 'def get_fitness(x, y):\n return x+y'
exec(s)

class t(object):
    def fnGetFitness(self,genes):
        return get_fitness(genes, 10)

    simulator(fnGetFitness)

t()

这解决了它,但说实话,我对目的感到困惑(我已经花了一段时间才弄清楚如何从你的代码中运行某些东西)

编辑:评论中发布了一个更简单且有所不同(与 exec 相关)的代码:

class t(object):
    def __init__(self):
        exec('def get_fitness(x, y):\n return x+y')
        print(get_fitness(2,3))
t()

这会引发NameError:名称'get_fitness'未定义

现在这与exec有关。当解析 __init__ 时,get_fitness 是未知的,因为解析器没有将其视为局部变量,即使在执行时,它被设置在 locals() 字典,由 exec 编写(相关:why is 'ord' seen as an unassigned variable here?)。

解决方法是在局部变量中获取函数,如下所示:

class t(object):
    def __init__(self):
        exec('def get_fitness(x, y):\n return x+y')
        print(locals()["get_fitness"](2,3))

t()

这有效并打印5

关于python - 为什么当我要在 Python 中传递动态函数时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52913196/

相关文章:

python - 在python中创建2 '*'的递归幂

python - pygame移动方 block 超出边界

python - 无法使用请求从网站获取一些数字

c# - 将一个对象放在 ILGenerator 中的堆栈顶部

python - 将元组转换为两部分

Python 拉丁字符和 Unicode

objective-c - 使用动态代码枚举 NSArray 的 block 闭包和三元运算符

c# - 像系统一样的工作流来改变代码流

python - 如何修复文件移动脚本读取文件名时出现 FileNotFoundError 错误?

python -c cmd 将等待所有进程完成