运行 PyCharm 中的 exec() 与 Jupyter Lab

Run exec() in PyCharm vs Jupyter Lab

我使用 python3.6,并尝试使用从 .yml 文件加载的 lambda 函数。我有 str 格式的 lambda,所以我使用 exec('l = lambda x: print(x)') 函数将其转换为有效的 lambda 并将其分配给变量,但它抛出 NameError: name 'l' is not defined 当我尝试使用 lambda

时出现异常

以下玩具示例演示了我的问题:

import pandas as pd

exec('l = lambda x: x+1')
df = pd.DataFrame(dict(a=[1, 2, 3], b=[4, 5, 6]))
df.loc[:, 'c'] = df.loc[:, 'a'].apply(l)
df

此代码 运行 在 Jupyter Lab 中很好,但是当我 运行 通过 PyCharm 时会导致 NameError: name 'l' is not defined 异常。 此外,当我在 PyCharm 中使用 debug 模式并尝试评估 l - 它确实表明这是一个 <function <lambda> at 0x7fe604a13f28>

我做错了什么?为什么在 JupyterLab 和 PyCharm 调试模式下它有效,但在我 运行 时却无效 PyCharm?

非常感谢任何帮助。

执行 exec 不会自动将内容放入您的全局范围。如果要将exec中的变量加入全局作用域,那么需要做如下操作:

exec('l = lambda x: x + 1', globals())

然后,您可以将 l 用作 exec 范围之外的函数。但是,这不是做事的好方法。

我相信 JupyterLab 会自动将 exec 添加到您的全局范围中,这会导致很多您不希望出现的副作用。但是,这在类似控制台的环境中是正常的。因此,如果您要 运行 在 PyCharm 控制台中的示例中的代码,它会起作用。

另一种方法是使用 eval() 而不是 exec(str, globals()),如 @Games Brainiac 所建议:

import pandas as pd

df = pd.DataFrame(dict(a=[1, 2, 3], b=[4, 5, 6]))
df.loc[:, 'c'] = df.loc[:, 'a'].apply(eval('lambda x: x+1'))
df

干杯