Python 有没有办法在for循环中更改全局函数,而不是创建一个新函数? 关于工作代码

Python 有没有办法在for循环中更改全局函数,而不是创建一个新函数? 关于工作代码,python,global-variables,Python,Global Variables,当我运行以下代码时,我看到它们按预期工作 def modify_string(n): str1 = ", ".join([f"arg{i}" for i in range(n)]) str2 = f"func{len(str1.split(', ')) - 1}"\ f"({', '.join(str1.split(', ')[:-1])})" return f"la

当我运行以下代码时,我看到它们按预期工作

def modify_string(n):
    str1 = ", ".join([f"arg{i}" for i in range(n)])
    str2 = f"func{len(str1.split(', ')) - 1}"\
        f"({', '.join(str1.split(', ')[:-1])})"
    return f"lambda {str1}: list(map(lambda i: list({str2})," \
        f" range({str1.split(', ')[-1]})))"


def create_globals(n):
    global func1
    func1 = lambda x: list(map(lambda j: 0, range(x)))
    for i in range(2, n + 1):
        globals()[f"func{i}"] = eval(modify_string(i)) 


create_globals(3)
print(func3(3, 2, 4))
输出:

[[[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]]]
func = lambda arg0, arg1: list(map(lambda i: list(func(arg0)), range(arg1)))
func = lambda arg0, arg1, arg2: list(map(lambda i: list(func(arg0, arg1)), range(arg2)))
当调用
create炣globals(n)
函数时,将定义不同的函数。函数的名称根据
i
编号而变化。每个创建的函数都将成为下一步中要创建的函数的参数:

在for循环的第一步中,定义了以下函数:

func2 = lambda arg0, arg1: list(map(lambda i: list(func1(arg0)), range(arg1)))
func3 = lambda arg0, arg1, arg2: list(map(lambda i: list(func2(arg0, arg1)), range(arg2)))
在for循环的第二步中,定义了以下函数:

func2 = lambda arg0, arg1: list(map(lambda i: list(func1(arg0)), range(arg1)))
func3 = lambda arg0, arg1, arg2: list(map(lambda i: list(func2(arg0, arg1)), range(arg2)))
这是一个函数,它可以创建n维矩阵

关于这个问题 我试图做的是,通过在每个步骤中使用相同的函数全局名称来定义新函数。最后我想使用上次创建的函数。这就是我更改代码的原因,如下所示:

def modify_string(n):
    str1 = ", ".join([f"arg{i}" for i in range(n)])
    str2 = f"func({', '.join(str1.split(', ')[:-1])})"
    return f"lambda {str1}: list(map(lambda i: list({str2})," \
        f" range({str1.split(', ')[-1]})))"


def create_globals(n):
    global func
    func = lambda x: list(map(lambda j: 0, range(x)))
    for i in range(2, n + 1):
        globals()["func"] = eval(modify_string(i))
        print("func =", modify_string(i))


create_globals(3)
输出:

[[[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]]]
func = lambda arg0, arg1: list(map(lambda i: list(func(arg0)), range(arg1)))
func = lambda arg0, arg1, arg2: list(map(lambda i: list(func(arg0, arg1)), range(arg2)))
产出似乎和预期的一样。 然而,当我调用类似于
func(3,2,4)
的函数时,我得到了一个
TypeError

func = lambda arg0, arg1: list(map(lambda i: list(func(arg0)), range(arg1)))
func = lambda arg0, arg1, arg2: list(map(lambda i: list(func(arg0, arg1)), range(arg2)))
Traceback (most recent call last):
  File "./a.py", line 21, in <module>
    func(2, 3, 4)
  File "<string>", line 1, in <lambda>
  File "<string>", line 1, in <lambda>
TypeError: <lambda>() missing 1 required positional argument: 'arg2'
func=lambda arg0,arg1:list(映射(lambda i:list(func(arg0)),范围(arg1)))
func=lambda arg0,arg1,arg2:list(映射(lambda i:list(func(arg0,arg1)),范围(arg2)))
回溯(最近一次呼叫最后一次):
文件“/a.py”,第21行,在
func(2,3,4)
文件“”,第1行,在
文件“”,第1行,在
TypeError:()缺少1个必需的位置参数:“arg2”
尽管我已经编写了
arg2
,但解释器的反应就像缺少
arg2
一样。你能解释一下为什么会这样吗


提前感谢。

函数通过在每次访问时查阅其
globals()
-来查找非局部变量的非限定名称。(这就是
def current():返回计数器
的工作原理。)因此,在单个名称下创建的每个函数(调用时)都指向所创建的最终函数,而不是任何以前的版本

构造和执行之间的这种脱节是不生成代码和
eval
it的众多原因之一。在这种情况下,为什么不使用一个带有变量的函数来调用带有前缀的参数呢

def mat(*n):
  return [mat(*n[:-1]) for _ in range(n[-1])] if n else 0

我不能给你们提供精确的解决方案,但你们没想过递归实现吗?不,我没想过。我这样想:假设我在第一行定义了
globals()[“f”]=1
。然后我在第二行定义了
globals()[“f”]=1+f
。如果我打印
f
,结果将是2。这就是为什么我认为我可以做类似的操作,而不是创建新的全局变量。在我看来,您不应该以这种方式修改全局状态并使用数据结构(如
list
dict
),但我共享的第一个代码可以正常工作。为什么我共享的第二个代码会引发
TypeError
?甚至不值得调试您试图创建的怪物。是的,没错。在每个创建的函数中,调用先前创建的函数
在这种情况下,为什么不使用一个具有可变数量的参数的函数,并使用它们的前缀调用自身呢?
根据我编写的代码,要生成
n
维矩阵函数,`(n-1)`需要创建大量的函数。因为每个函数都调用前一个函数。你能给我举一个你建议的方法的例子吗?(顺便问一下,您认为您所问的问题是否与我共享的第一个代码有关?@dildeolupbiten:不,在创建的每个函数中,调用都与调用之前最近创建的相同。