【问题标题】:Defining functions dynamically does not work inside class objects?动态定义函数在类对象中不起作用?
【发布时间】:2021-08-07 01:37:49
【问题描述】:

在我当前的项目中,我通过组装一个字符串、执行该字符串,然后将生成的函数附加到一个列表来动态构造函数。这在控制台中运行良好,即使在循环时也是如此,但奇怪的是,当我尝试在类对象中做同样的事情时它不起作用。你知道为什么,我怎样才能让它发挥作用吗?

下面的示例 sn-p 是一个最小示例。从字符串构造函数在主脚本中不是问题,但是当在类对象中使用时,函数不再被组装并且尝试将其附加到列表会返回错误。

import numpy as np

# Create a string for a function
funstr  = "def fun1(x): return x"

# Create a function
exec(funstr)

# Call the function
print('Evaluate the function:')
print(fun1(5))
print('Success!')

# Create functions in a loop
funlist = []
for i in range(5):
    funstr  = "def fun2(x): return x+"+str(i)
    exec(funstr)
    funlist.append(fun2)

# Check if the stored functions work
print('Evaluate the list functions:')
for i in range(5):
    print(funlist[i](5))
print('Success!')

# Try the same thing in a class
class testobject:
    
    def build_functions(self):
        
        # Do the same thing we did outside inside the class
        self.funlist = []
        for i in range(5):
            funstr  = "def fun3(x): return x+"+str(i)
            exec(funstr)
            print("Here, a function fun3 should have been assembled. For some reason, it hasn't been.")
            # !! Here, the function crashes because 'fun3' does not exist. !!
            self.funlist.append(fun3)
            
        print('Evaluate the list functions inside the object:')
        for i in range(5):
            print(self.funlist[i](5))
            
# Initialize an object
obj     = testobject()

# Create the functions inside
obj.build_functions()

【问题讨论】:

  • 我怀疑问题是exec() 在本地范围内定义函数。但是由于编译器在代码中没有看到任何fun3 的赋值,所以它在全局范围内寻找变量。
  • @J.Galt 如果不是 lambda,则使用闭包。从字符串定义函数是基本问题,尝试找到更好的方法。
  • 最初的问题是,为什么需要从字符串创建函数?
  • 问题与类对象无关。如果我在普通函数中使用类似的代码,我会遇到同样的问题。
  • def build_function(i): funstr = "def fun3(x): return x+"+str(i) exec(funstr) print(fun3(5))

标签: python function class oop


【解决方案1】:

fun3 是在局部范围内定义的,但self.funlist.append(fun3) 是在全局范围内寻找变量fun3(因为在函数的源代码中没有可见的局部变量定义)。

您可以使用locals() 函数获取局部变量的字典。

self.funlist.append(locals()['fun3'])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-12
    • 2016-05-12
    • 1970-01-01
    • 2012-02-26
    • 2022-01-17
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多