Python中的eval() & exec()

这篇具有很好参考价值的文章主要介绍了Python中的eval() & exec()。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

eval()

eval() 是一个内置的 Python 函数,它允许执行一个字符串作为 Python 表达式并返回结果。换句话说,它可以从字符串中动态地执行 Python 表达式。

eval 函数的完整签名是:

eval(expression, globals=None, locals=None)
  • expression: 必须的参数。这是要计算的 Python 表达式,以字符串形式给出。
  • globals: 可选的参数。这是用于提供全局命名空间(即全局变量)的字典。在上面的例子中,它被设置为 None,这意味着它将使用当前的全局命名空间。
  • locals: 可选的参数。这是用于提供局部命名空间(即局部变量)的字典。

例如:

local_vars = {'a': 5, 'b': 3}
result = eval("a + b", None, local_vars)
print(result)  # 输出:8

在这个例子中,在表达式 eval("a + b", None, local_vars) 中,eval 函数用于计算一个字符串表达式并返回其结果。此表达式尝试对变量 ab 进行加法操作。ab 的值(分别为 5 和 3)是从 local_vars 字典中获取的,并且它们的和(8)被返回。

  • "a + b": 这是要计算的表达式。
  • None: 这表示不使用任何特定的全局命名空间,而是使用当前的全局命名空间。
  • local_vars: 这是一个开发者提供的字典,包含局部变量。函数将尝试在这个字典中查找 ab 的值。如果这个字典确实包含了 ab 的值,那么它们的值将被用于加法操作【1】。

基本用法:

result = eval("5 + 3")
print(result)  # 输出: 8

可以处理复杂的表达式:

x = 10
result = eval("x * 3 + 2")
print(result)  # 输出: 32

可以使用本地和全局命名空间:

这意味着我们可以在 eval() 内部访问和修改变量。

local_vars = {"a": 5, "b": 3}
result = eval("a + b", None, local_vars)
print(result)  # 输出: 8

安全性问题:

使用 eval() 需要谨慎,因为它允许执行任意代码。这可能会导致安全风险,特别是当我们从不受信任的来源获取字符串并用 eval() 执行时。例如:

# 永远不要这样做!
dangerous_string = "os.system('rm -rf /')"  # 这将删除你的文件系统!
eval(dangerous_string)  

为了避免潜在的安全风险,不要使用 eval() 除非我们完全信任源,并且确信没有更好的方法来达到同样的目的。

exec() 的区别:

  • eval() 只能计算单个表达式并返回值,而 exec() 可以执行更复杂的 Python 代码块,但不返回任何值。
x = 10
eval("x = x + 5")  # 这会引发语法错误,因为赋值不是一个表达式

exec("x = x + 5")  # 这是有效的

总之,尽管 eval() 是一个强大的工具,但它必须小心且明智地使用,尤其要注意其安全性问题。

exec()

exec() 是 Python 的一个内置函数,用于动态地执行 Python 程序,可以是一个字符串或对象代码(例如由 compile() 生成的代码对象)。这使得可以在运行时动态地生成和执行代码。与 eval() 不同,exec() 可以执行更复杂的代码块(如多行代码、声明和控制流语句),而不仅仅是单一的表达式。

exec() 的函数签名如下:

exec(source, globals=None, locals=None)
  • source:必需参数。表示要执行的 Python 代码。它可以是普通的字符串、字节字符串,或者是由 compile() 函数返回的代码对象。

  • globals:可选参数。表示全局命名空间(变量)的字典。如果提供了此参数,则在执行代码时会使用这个字典作为全局命名空间。否则,exec() 会使用当前全局命名空间。

  • locals:可选参数。表示局部命名空间(变量)的字典。如果提供了此参数,则在执行代码时会使用这个字典作为局部命名空间。如果没有提供,它会使用 globals 字典(这意味着,如果只提供 globals,那么它将同时用作全局和局部命名空间)。

关于 globalslocals 的一些注意事项:

  1. 如果 exec() 只提供了 source,不指定 globalslocals,那么它将在当前全局和局部命名空间中执行。
  2. 如果提供了 globals 字典,但没有提供 locals 字典,那么 globals 会同时作为全局和局部命名空间。
  3. 如果同时提供了 globalslocals 字典,那么它们分别会被用作各自的命名空间。
  4. 尽管 globalslocals 的名字可能让人觉得它们只能用于存储变量,但实际上它们可以包含函数、类等任何 Python 对象。

例子:

x = 10

def test_exec(source, g=None, l=None):
    exec(source, g, l)

global_dict = {'x': 20}
local_dict = {'x': 30}

# 使用默认的全局和局部命名空间
test_exec('print(x)')  # 输出: 10

# 使用指定的全局命名空间
test_exec('print(x)', global_dict)  # 输出: 20

# 使用指定的全局和局部命名空间
test_exec('print(x)', global_dict, local_dict)  # 输出: 30

请注意,由于 exec() 可以执行任意代码,因此必须谨慎使用它,以避免潜在的安全风险。特别是当执行的代码来源于不受信任的来源时。

基本用法:

可以使用 exec() 执行字符串中的任何有效的 Python 代码:

code = """
x = 10
y = 20
print(x + y)
"""
exec(code)  # 输出: 30

作用域:

默认情况下,exec() 将在调用它的当前命名空间(即本地和全局变量)中执行。但我们可以为其提供单独的命名空间:

globals_var = {"a": 10}
locals_var = {"b": 20}
code = "result = a + b"

exec(code, globals_var, locals_var)
print(locals_var["result"])  # 输出: 30

安全性:

eval() 一样,exec() 也带有安全风险。它可以执行任意的 Python 代码,这意味着恶意代码可以导致数据泄露、数据损坏或其他安全隐患。因此,使用 exec() 时必须非常小心,尤其是当我们执行的代码来自不受信任的来源时。

返回值:

exec() 不返回任何值(即它的返回值是 None)。它只是执行给定的代码。

eval() 的对比:

  • eval() 用于计算单个表达式并返回其值。
  • exec() 用于执行任意的代码块(无论其复杂度如何)并不返回任何值。

示例:

使用 exec() 动态地定义和调用函数:

code = """
def greet(name):
    return f"Hello, {name}!"
"""

exec(code)

# 使用 exec 中定义的函数
greeting = greet("Alice")
print(greeting)  # 输出: Hello, Alice!

总的来说,exec() 是一个强大的函数,允许我们动态地执行 Python 代码。然而,由于潜在的安全风险,建议在非常受限制和受控制的环境中使用它,并尽量避免执行不受信任的代码。


注【1】 如果 local_vars 字典不包含 ab 的值,eval 函数会产生一个 NameError

例如:

local_vars = {'a': 5}
result = eval("a + b", None, local_vars)

上述代码将抛出以下异常:

NameError: name 'b' is not defined

这是因为在提供的 local_vars 字典中,b 的值没有被定义。

但是,值得注意的是,如果 ab 既不在 local_vars 中,也不在当前的全局命名空间中,则会抛出这个异常。如果它们在当前的全局命名空间中有定义,那么这些全局值将被使用。

例如:

a = 10
b = 20
local_vars = {'a': 5}
result = eval("a + b", None, local_vars)
print(result)  # 输出:25

在这个例子中,尽管 b 没有在 local_vars 字典中定义,但它在全局命名空间中有定义,所以其值 20 被使用了。而 a 的值从 local_vars 中取得,即 5。所以最终的结果是 5 + 20 = 25


在 Python 中,每个代码块(如函数、模块、类等)都有其自己的命名空间。这个命名空间是一个存储所有在该代码块中定义的变量、函数、类等标识符的字典。当我们在代码中引用一个变量或函数名时,Python 会查找这个命名空间来获取它的值。

  • 全局命名空间:这是与特定模块相关的命名空间。当我们在模块级别定义变量或函数时(即不在任何函数或类内部),它们被添加到这个全局命名空间。在模块内,可以通过内置的 globals() 函数来获取这个命名空间的字典。

  • 局部命名空间:当我们在一个函数或方法内部定义变量或函数时,它们被添加到局部命名空间。局部命名空间仅在其相应的函数或方法内部可用,并在函数执行完毕后被销毁。在函数内,可以通过内置的 locals() 函数来获取这个命名空间的字典。

例如:

x = 10  # 这个变量在全局命名空间

def some_function():
    y = 5  # 这个变量在 some_function 的局部命名空间
    print("Locals:", locals())

some_function()
print("Globals:", globals())

在这个例子中:

  • x 是全局变量,因为它是在模块级别定义的,所以它在全局命名空间中。
  • y 是局部变量,因为它是在 some_function 内部定义的,所以它在这个函数的局部命名空间中。

当我们说“默认的全局和局部命名空间”时,我们是指:

  • 在函数内部,如果没有指定其他的命名空间,局部命名空间就是该函数的命名空间,而全局命名空间是模块的命名空间。

  • 在模块级别(即不在任何函数内部),全局命名空间和局部命名空间实际上是相同的,都是模块的命名空间。

这种分层的命名空间结构使得变量的查找和作用域的管理变得明确和灵活。当在一个函数内部引用一个变量时,Python 首先会查找局部命名空间。如果没有找到,它会继续在全局命名空间中查找,然后继续在更高级的命名空间中查找,直到达到内置命名空间。


有关Python中的命名空间详情请参考 Python中的命名空间文章来源地址https://www.toymoban.com/news/detail-725549.html

到了这里,关于Python中的eval() & exec()的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python literal_eval()函数

    python literal_eval 函数是Python的内置函数 eval 的一个变体,用于安全地评估并执行一个Python表达式。 literal_eval 函数可以评估一个包含字面值的字符串,并返回其对应的Python对象。字面值可以是数字、字符串、列表、字典、元组和布尔值。 函数原型: ast.literal_eval(node_or_string)

    2024年01月23日
    浏览(39)
  • 深入了解Python的eval函数:基础用法与潜在危险【第118篇—eval函数】

    在Python中, eval 函数是一个强大而灵活的工具,它允许将字符串作为代码来执行。然而,虽然 eval 在某些情况下非常方便,但它也潜藏着一些潜在的危险,如果不小心使用,可能导致安全性问题。在本文中,我们将深入探讨 eval 函数的基础用法,并提供一些使用该函数时需要

    2024年03月12日
    浏览(47)
  • python的exec函数

    exec() 是 Python 内置的一个函数,用于在运行时执行动态生成的 Python 代码。它以字符串形式接收一个代码块,并将其编译并执行为可执行的 Python 代码。 exec() 函数的语法如下: object :必需,表示要执行的代码块。它可以是以下类型之一: 字符串:包含要执行的 Python 代码的

    2024年02月10日
    浏览(31)
  • Python中利用exec批量生成变量

    函数概括 eval():函数用来执行一个字符串表达式,并返回表达式的值。 注意:计算指定表达式的值。也就是说它要执行的python代码只能是单个表达式(注意eval不支持任何形式的赋值操作),而不能是复杂的代码逻辑 exec():执行储存在字符串或文件中的 Python 语句 注意:动态执行

    2023年04月16日
    浏览(25)
  • Python-VBA函数之旅-exec函数

    目录 一、exec函数的常见应用场景: 二、exec函数安全使用注意事项: 三、exec函数与eval函数对比分析: 1、exec函数: 1-1、Python: 1-2、VBA: 2、相关文章: 个人主页:神奇夜光杯-CSDN博客  一、exec函数的常见应用场景:         exec函数 在Python中有多种实际应用场景,尽管

    2024年04月25日
    浏览(36)
  • Python内置函数--input(),print(),eval()三个函数的 功能与运用格式

    Python解释器内置了许多不同功能和类型的函数,今天就给大家简单的介绍三种内置函数及功能: Python之input 函数的用法 1、接收一个标准输入数据,返回string类型 2、在命令行输入一行信息,会将这行信息返回成字符   Python之eval函数的用法 功能:将字符串str当成有效的表达

    2023年04月14日
    浏览(48)
  • MVSNet、PatchMatchNet中的 eval.sh文件超参数解释

    下面以PatchMatchNet为例, 打开PatchMatchNet程序中的 eavl.sh文件, 可以看到文件设置了数据集路径,及超参数设置(超参数,也可以不写,会使用默认参数) 上图中各参数意思如下:

    2024年02月17日
    浏览(51)
  • 深入理解PyTorch中的train()、eval()和no_grad()

    ❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️ 👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博相关......)👈 (封面图由文心一格生成) 在PyTorch中,train()、eval()和no_grad()是三个非常重

    2023年04月08日
    浏览(49)
  • MySQL中的slave_exec_mode 参数详解(MySQL从节点复制错误处理时,sql_slave_skip_counter VS slave-skip-errors VS slave_exec_mode)(译)

    原文地址:https://www.soughttech.com/front/article/7159/viewArticle     今天我偶然看到了参数slave_exec_mode。从手册中的描述可以看出,该参数与MySQL复制有关。它是一个可以动态修改的变量。默认为STRICT mode(严格模式),可选值为IDEMPOTENT mode(幂等模式)。 设置为IDEMPOTENT模式可以防止从库

    2024年02月05日
    浏览(52)
  • (译)MySQL中的slave_exec_mode 参数详解(MySQL从节点跳过复制错误的处理,sql_slave_skip_counter VS slave-skip-errors VS slave_exec_mode)

    原文地址:https://www.soughttech.com/front/article/7159/viewArticle     今天我偶然看到了参数slave_exec_mode。从手册中的描述可以看出,该参数与MySQL复制有关。它是一个可以动态修改的变量。默认为STRICT mode(严格模式),可选值为IDEMPOTENT mode(幂等模式)。 设置为IDEMPOTENT模式可以防止从库

    2024年02月05日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包