我想使用 Python 中的正常 def 过程创建函数,并将标签分配给从字符串列表中提取的命名空间。如何实现这一点?
这个问题的动机:我正在创建一个与 sympy 兼容的 python 函数库,供数学家用于符号计算实验。许多函数需要初始化具有相关标签的多个对象的系统,这些标签分别由用户提供的字符串生成。为了生成这些标签,我根据用户提供的字符串构建了一个字符串列表。然后,我继续将此字符串列表中的标签分配给正在定义的各种对象,通常是通过直接更新 globals() 字典。然而,一些被定义的对象本身就是函数,这就是这个问题的原因。
一个具体的例子:一个函数应该允许用户使用他们想要的任何标签初始化变量,并同时初始化表示与这些对偶的坐标向量场的对象变量(我们在 python 中将其定义为函数)。用户应该为其变量指定标签,然后函数应该为向量场对象生成相关标签。例如,如果用户选择变量标签“x”,则该函数应自动标记创建的向量场对象“D_x”。这只是我需要实现这种构造的许多示例之一,这就是为什么在目前的一般性中提出这个问题的原因。
示例问题:给定任意字符串列表 exampleList=['label1','label2 ','label3',...] 长度为 k,以编程方式初始化
exampleList=['label1','label2','label3','label4']
def label1(arg: str):
if len(arg)>exampleList[0]
print('the word '+arg+' has more letters than the word '+exampleList[0])
def label2(arg: str):
if len(arg)>exampleList[1]
print('the word '+arg+' has more letters than the word '+exampleList[1])
# ...etc.
形式的 k def 定义函数。
如果要定义的函数仅涉及 lambda 函数内可实现的操作,则可以使用lambda 通过更新 globals() 字典来运行。例如,可以编写类似
exampleList=['label1','label2','label3']
exampleOperation= lambda j,k: len(j)-len(k)
globals().update(zip(exampleList,[lambda k:exampleOperation(j,k) for j in exampleList]))
的内容,上面的示例使用从列表
exampleList
分配的标签初始化了一些 lambda 函数。然而,我希望使用普通的 def 定义函数而不是 lambda 函数来完成类似的任务。
你可以使用
exec
函数动态定义函数。但是,直接操作
globals()
通常被认为是不好的做法,因为它可能会导致难以调试的代码。
以下是如何使用字典来保存函数并实现所需结果的方法:
def create_functions(exampleList):
"""根据提供的标签列表创建比较函数。
Args:
exampleList: 字符串标签列表。
Returns:
一个包含已创建函数的字典,其中键是标签。
"""
functions = {}
for i, label in enumerate(exampleList):
def make_function(i): # 使用闭包来捕获当前的 'i' 值
def function(arg: str):
if len(arg) > len(exampleList[i]):
print(f"单词 '{arg}' 的字母比单词 '{exampleList[i]}' 多")
return function
functions[label] = make_function(i)
return functions
# 示例用法
exampleList = ['label1', 'label2', 'label3', 'label4']
functions = create_functions(exampleList)
# 现在你可以通过它们的标签访问函数
functions['label1']("test") # 这将打印出该消息,因为“test”比“label1”长
functions['label2']("a") # 这不会打印任何内容
这个代码片段执行以下操作:
-
create_functions(exampleList)
: - 它接受一个标签列表作为输入。
-
它创建一个空字典
functions
来存储生成的函数。 - 它遍历列表中的每个标签。
-
make_function(i)
: 对于每个标签,它都会定义一个嵌套函数,该函数捕获当前的索引i
。这样做是为了避免 Python 中常见的“迟绑定闭包”问题。 -
function(arg: str)
: 这个内部函数就是你的比较函数。它将输入字符串与exampleList
中相应索引处的标签进行比较。 -
生成的函数存储在
functions
字典中,其中键是标签,值是函数。 -
示例用法:
-
它调用
create_functions
来使用你的示例列表生成函数。 - 然后,它演示如何通过它们的标签访问和使用生成的函数。
这个方法避免了直接操作
globals()
,并提供了对已创建函数的更清晰、更有条理的管理。