得之我幸 失之我命

when someone abandons you,it is him that gets loss because he lost someone who truly loves him but you just lost one who doesn’t love you.

Python 中 eval 和 exec1

eval 函数

  1. 函数的作用:

    计算指定表达式的值。也就是说它要执行的 Python 代码只能是单个运算表达式(注意 eval 不支持任意形式的赋值操作),而不能是复杂的代码逻辑,这一点和 lambda 表达式比较相似。

  2. 函数定义:

    eval(expression, globals=None, locals=None)

  3. 参数说明:

    • expression:必选参数,可以是字符串,也可以是一个任意的 code 对象实例(可以通过 compile 函数创建)。如果它是一个字符串,它会被当作一个(使用 globals 和 locals 参数作为全局和本地命名空间的)Python 表达式进行分析和解释。
    • globals:可选参数,表示全局命名空间(存放全局变量),如果被提供,则必须是一个字典对象。
    • locals:可选参数,表示当前局部命名空间(存放局部变量),如果被提供,可以是任何映射对象。如果该参数被忽略,那么它将会取与 globals 相同的值。
    • 如果 globals 与 locals 都被忽略,那么它们将取 eval() 函数被调用环境下的全局命名空间和局部命名空间。
  4. 返回值:

    • expression 是一个 code 对象,且创建该 code 对象时,compile 函数的 mode 参数是 ‘exec’,那么 eval() 函数的返回值是 None;
    • expression 是一个输出语句,如 print(),则 eval() 返回结果为 None;
    • expression 表达式的结果就是 eval() 函数的返回值;
  5. 实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    x = 10

    def func():
    y = 20
    a = eval('x + y')
    print('a: ', a)
    b = eval('x + y', {'x': 1, 'y': 2})
    print('b: ', b)
    c = eval('x + y', {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
    print('c: ', c)
    d = eval('print(x, y)')
    print('d: ', d)

    func()

    # 输出结果:
    a: 30 # eval 函数的 globals 和 locals 参数都被忽略了,因此变量 x 和变量 y 都取得的是 eval 函数被调用环境下的作用域中的变量值,即:x = 10, y = 20,a = x + y = 30
    b: 3 # eval 函数只提供了 globals 参数而忽略了 locals 参数,因此 locals 会取 globals 参数的值,即:x = 1, y = 2,b = x + y = 3
    c: 4 # eval 函数的 globals 参数和 locals 都被提供了,那么 eval 函数会先从全部作用域 globals 中找到变量 x, 从局部作用域 locals 中找到变量 y,即:x = 1, y = 3, c = x + y = 4
    10 20
    d: None # 因为 print() 函数不是一个计算表达式,没有计算结果,因此返回值为 None

exec 函数

  1. 函数的作用:

    动态执行Python代码。也就是说exec可以执行复杂的Python代码,而不像eval函数那么样只能计算一个表达式的值。

  2. 函数定义:

    exec(object[, globals[, locals]])

  3. 参数说明:

    • object:必选参数,表示需要被指定的 Python 代码。它必须是字符串或 code 对象。如果 object 是一个字符串,该字符串会先被解析为一组 Python 语句,然后在执行(除非发生语法错误)。如果object 是一个 code 对象,那么它只是被简单的执行。
    • globals:可选参数,同 eval 函数
    • locals:可选参数,同 eval 函数
  4. 返回值:

    • exec 函数的返回值永远为 None.
  5. 注意:

    需要说明的是在 Python2 中 exec 不是函数,而是一个内置语句(statement),但是 Python2 中有一个 execfile() 函数。可以理解为 Python3 把 exec 这个 statement 和 execfile() 函数的功能够整合到一个新的 exec() 函数中去了:

eval() 函数与 exec() 函数的区别

  1. eval() 函数只能计算单个表达式的值,而 exec() 函数可以动态运行代码段。

  2. eval() 函数可以有返回值,而 exec() 函数返回值永远为 None。

  3. 实例1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    x = 10

    def func():
    y = 20
    a = exec('x + y')
    print('a: ', a)
    b = exec('x + y', {'x': 1, 'y': 2})
    print('b: ', b)
    c = exec('x + y', {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
    print('c: ', c)
    d = exec('print(x, y)')
    print('d: ', d)

    func()

    # 输出结果:
    a: None
    b: None
    c: None
    10 20
    d: None
    # 因为exec 函数的返回值永远为 None。
  4. 实例2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    x = 10
    expr = """
    z = 30
    sum = x + y + z
    print(sum)
    """
    def func():
    y = 20
    exec(expr)
    exec(expr, {'x': 1, 'y': 2})
    exec(expr, {'x': 1, 'y': 2}, {'y': 3, 'z': 4})

    func()

    # 输出结果:
    60
    33
    34

globals() 与 locals() 函数

  1. globals()

    Return a dictionary representing the current global symbol table. This is always the dictionary of the current module (inside a function or method, this is the module where it is defined, not the module from which it is called).

    翻译:返回一个表示当前全局标识符表的字典。这永远是当前模块的字典(在一个函数或方法内部,这是指定义该函数或方法的模块,而不是调用该函数或方法的模块)

  2. locals()

    Update and return a dictionary representing the current local symbol table. Free variables are returned by locals() when it is called in function blocks, but not in class blocks.

    Note The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.

    翻译:更新并返回一个表示当前局部标识符表的字典。自由变量在函数内部被调用时,会被 locals() 函数返回;自由变量在类累不被调用时,不会被 locals() 函数返回。

    注意:locals() 返回的字典的内容不应该被改变;如果一定要改变,不应该影响被解释器使用的局部变量和自由变量。

  3. 总结:

    • globals() 函数以字典的形式返回的定义该函数的模块内的全局作用域下的所有标识符(变量、常量等)
    • locals() 函数以字典的形式返回当前函数内的局域作用域下的所有标识符
    • 如果直接在模块中调用 globals() 和 locals() 函数,它们的返回值是相同的
  4. 实例1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    name = 'Tom'
    age = 18

    def func(x, y):
    sum = x + y
    _G = globals()
    _L = locals()
    print(id(_G), type(_G), _G)
    print(id(_L), type(_L), _L)

    func(10, 20)

    # 输出结果:
    2131520814344 <class 'dict'> {'__builtins__': <module 'builtins' (built-in)>, 'func': <function func at 0x000001F048C5E048>, '__doc__': None, '__file__': 'C:/Users/wader/PycharmProjects/LearnPython/day04/func5.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001F048BF4C50>, '__spec__': None, 'age': 18, '__name__': '__main__', 'name': 'Tom', '__package__': None, '__cached__': None}
    2131524302408 <class 'dict'> {'y': 20, 'x': 10, '_G': {'__builtins__': <module 'builtins' (built-in)>, 'func': <function func at 0x000001F048C5E048>, '__doc__': None, '__file__': 'C:/Users/wader/PycharmProjects/LearnPython/day04/func5.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001F048BF4C50>, '__spec__': None, 'age': 18, '__name__': '__main__', 'name': 'Tom', '__package__': None, '__cached__': None}, 'sum': 30}
  5. 实例2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    name = 'Tom'
    age = 18

    G = globals()
    L = locals()
    print(id(G), type(G), G)
    print(id(L), type(L), L)

    # 输出结果:
    2494347312392 <class 'dict'> {'__file__': 'C:/Users/wader/PycharmProjects/LearnPython/day04/func5.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000244C2E44C50>, 'name': 'Tom', '__spec__': None, '__builtins__': <module 'builtins' (built-in)>, '__cached__': None, 'L': {...}, '__package__': None, '__name__': '__main__', 'G': {...}, '__doc__': None, 'age': 18}
    2494347312392 <class 'dict'> {'__file__': 'C:/Users/wader/PycharmProjects/LearnPython/day04/func5.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000244C2E44C50>, 'name': 'Tom', '__spec__': None, '__builtins__': <module 'builtins' (built-in)>, '__cached__': None, 'L': {...}, '__package__': None, '__name__': '__main__', 'G': {...}, '__doc__': None, 'age': 18}

    # 上面打印出的G和L的内存地址是一样的,说明在模块级别 locals() 的返回值和 globals() 的返回值是相同的。

compile函数

  1. 函数的作用:

    将 source 编译为 code 对象或 AST 对象。code 对象能够通过 exec() 函数来执行或者通过 eval() 函数进行计算求值。

  2. 函数定义:

    compile(source, filename, mode[, flags[, dont_inherit]])

  3. 参数说明:

    • source:字符串或 AST(Abstract Syntax Trees)对象,表示需要进行编译的 Python 代码
    • filename:指定需要编译的代码文件名称,如果不是从文件读取代码则传递一些可辨认的值(通常是用 ‘’)
    • mode:用于标识必须当做那类代码来编译;如果 source 是由一个代码语句序列组成,则指定 mode=‘exec’;如果 source 是由单个表达式组成,则指定 mode=‘eval’;如果 source 是由一个单独的交互式语句组成,则指定 mode=‘single’。
    • 后续参数与编译相关
  4. 实例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    s = """
    for x in range(10):
    print(x, end='')
    print()
    """
    code_exec = compile(s, '<string>', 'exec')
    code_eval = compile('10 + 20', '<string>', 'eval')
    code_single = compile('name = input("Input Your Name: ")', '<string>', 'single')

    a = exec(code_exec)
    b = eval(code_eval)

    c = exec(code_single)
    d = eval(code_single)

    print('a: ', a)
    print('b: ', b)
    print('c: ', c)
    print('name: ', name)
    print('d: ', d)
    print('name; ', name)

    # 输出结果:
    0123456789
    Input Your Name: Tom
    Input Your Name: Jerry
    a: None
    b: 30
    c: None
    name: Jerry
    d: None
    name; Jerry

这几个函数的关系

  1. comiple() 函数、globals() 函数、locals() 函数的返回结果可以当作 eval() 函数与 exec() 函数的参数使用。
  2. 可以通过判断 globals() 函数的返回值中是否包含某个 key 来判断,某个全局变量是否已经存在(被定义)。

be slow to promise and quick to perform.