总结分析Python的5个硬核函数

对于想深入理解 Python 的朋友,很有必要认真看看。喜欢本文点赞支持,欢迎收藏学习。

1. eval函数

函数的作用:

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

函数定义:

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

参数说明:

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

返回值:

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

实例:

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
b: 3
c: 4
10 20
d: None

对输出结果的解释:

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

2. exec函数

函数的作用:

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

函数定义:

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

参数说明:

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

返回值:

exec函数的返回值永远为None.

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

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

  • eval()函数只能计算单个表达式的值,而exec()函数可以动态运行代码段。
  • eval()函数可以有返回值,而exec()函数返回值永远为None。

实例1:

我们把实例1中的eval函数换成exec函数试试:

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。

实例2:

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

对输出结果的解释:

前两个输出跟上面解释的eval函数执行过程一样,不做过多解释。关于最后一个数字34,我们可以看出是:x = 1, y = 3是没有疑问的。关于z为什么还是30而不是4,这其实也很简单,我们只需要在理一下代码执行过程就可以了,其执行过程相当于:

x = 1
y = 2

def func():
    y = 3
    z = 4

    z = 30
    sum = x + y + z
    print(sum)

func()

3. globals()与locals()函数

函数定义及功能说明:

先来看下这两个函数的定义和文档描述

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).

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

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()返回的字典的内容不应该被改变;如果一定要改变,不应该影响被解释器使用的局部变量和自由变量。

总结:

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

实例1:

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}

实例2:

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()的返回值是相同的。

4. compile函数

函数的作用:

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

函数定义:

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

参数说明:

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

实例:

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

5. 这几个函数的关系

comiple()函数、globals()函数、locals()函数的返回结果可以当作eval()函数与exec()函数的参数使用。

另外,我们可以通过判断globals()函数的返回值中是否包含某个key来判断,某个全局变量是否已经存在(被定义)。

技术交流

欢迎转载、收藏、有所收获点赞支持一下!

到此这篇关于总结分析Python的5个硬核函数的文章就介绍到这了,更多相关Python 函数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python基础之函数

    函数: # 什么是函数:一系列python语句的组合,可以在程序中运行一次或者多次 # 一般是完成具体的独立的功能 # 为什么要使用函数 # 代码的复用最大化以及最小化冗余代码,整体代码结构清晰,问题局部化 # 函数定义: # def 函数名() # 函数体[一系列的python语句,表示独立的功能] # 函数的调用: # 本质上就是去执行函数定义里面的代码块.在调用函数之前,必须先定义 printInfo() #函数的调用 函数名()#函数的调用 def printInfo(name,heig

  • python基础之引用和匿名函数

    a=1 #1 为对象, def func(x): print('x的地址{}'.format(id(x))) x=2 print('x的地址{}'.format(id(x))) pass # 调用函数 print('a的地址:{}'.format(id(a))) func(a) # 不可变类型 a=1 #1 为对象, ##传递的是一个对象的引用,并不是一个值 def func(x): print('x的地址{}'.format(id(x))) x=2 print('x的地址{}'.format(

  • Python基础常用内建函数图文示例解析

    目录 abs() all() any() bin() bool() callable() abs() 返回一个数字的绝对值,它的参数可以是整数或者浮点数.举个例子: all() 参数为一个可迭代对象,如果该可迭代对象所有元素的真值都为True(或者可迭代对象为空),则返回True.它等价于: 举个例子: any() 和all()函数相对应,如可迭代对象所有元素中只要有一个元素真值为True,那么就返回True,如果这个可迭代对象是空的,则返回True.它等价于: 举个例子: bin() 将整数转

  • python基础之递归函数

    # 递归满足的条件 # 1.自己调用自己 # 2.必须有一个明确的结束条件 # 优点:逻辑简单\定义简单 # 缺点:防止内存消耗过多,容易导致栈溢出,内存资源紧张,甚至内存泄漏事件发生 # 求阶乘 # 循环的方式去实现 def jiecheng(n): result=1 for item in range(1,n+1): result*=item pass return result #普通函数必须指定返回值 print('4的阶乘为{}'.format(jiecheng(4))) def di

  • Python之基础函数案例详解

    函数就是把具有独立功能的代码块封装成一个小模块,可以直接调用,从而提高代码的编写效率以及重用性, 需要注意的是, 函数需要被调用才会执行, 而调用函数需要根据函数名调用  函数的定义格式: def 函数名(): 函数代码 使用当前文件的函数 我们直接定义一个函数然后运行程序, 函数并不会被调用 def hello(): print('hello') 想要函数被执行, 需要使用函数名来调用函数 # 定义函数 def hello(): print('hello') # 调用函数 hello()  需

  • Python函数基础

    目录 Python函数 1.函数的定义格式 2.使用当前文件的函数 3.调用及定义函数 4.使用其他文件(模块)的函数 5.求两数之和 Python函数 函数就是把具有独立功能的代码块封装成一个小模块,可以直接调用,从而提高代码的编写效率以及重用性, 需要注意的是, 函数需要被调用才会执行, 而调用函数需要根据函数名调用 1.函数的定义格式 def 函数名(): 函数代码 2.使用当前文件的函数 我们直接定义一个函数然后运行程序, 函数并不会被调用 def hello(): print('hel

  • python基础之内置函数

    https://docs.python.org/3/library/function.html #python官方网址 # 取绝对值 print(abs(-34)) # 取参数的近似值,精度与版本有关 print(round(3.66)) # 求次方 print(3**5) print(pow(3,5)) #求3的5次方 # max求最大值 print(max([23,123,13455,14664345,243565])) # eval 执行表达式 a,b,c=1,2,3 print('动态执

  • 总结分析Python的5个硬核函数

    对于想深入理解 Python 的朋友,很有必要认真看看.喜欢本文点赞支持,欢迎收藏学习. 1. eval函数 函数的作用: 计算指定表达式的值.也就是说它要执行的Python代码只能是单个运算表达式(注意eval不支持任意形式的赋值操作),而不能是复杂的代码逻辑,这一点和lambda表达式比较相似. 函数定义: eval(expression, globals=None, locals=None) 参数说明: expression:必选参数,可以是字符串,也可以是一个任意的code对象实例(可以

  • 分析Python读取文件时的路径问题

    Python在读取文件内容时的路径问题,值得深究一下.我想讨论的重点还是在绝对路径上面.在这之前我们先看一下 1:相对路径 这张图演示了在相对路径下寻找查找指定文件.  open('相对路径演示'\'相对路径示例'.txt)打开的是相对当前运行的程序所在目录. 而我当前运行的程序相对位置在桌面. 所以直接print(lines) 可以看到这个结果 2:绝对路径. 绝对路径的查找方法就不演示了,相信每个人都会找到.但是我想讨论的是几个关于路径中的编码问题,相信这对初学者们有很大的帮助. 2.1:你

  • 详细分析Python垃圾回收机制

    引入 为什么要有垃圾回收机制 Python中的垃圾回收机制简称(GC),我们在程序的运行中会产生大量的变量用于保存数据,而有时候有些变量已经没有用了就需要被清理释放掉该变量所占据的内存空间.在一些较为低级的语言中(比如:C语言,汇编语言)对于内存空间的释放是需要编程人员来手动进行的,这种与底层硬件直接打交道的操作是十分的危险与繁琐的,而基于C语言开发而来的Python为了解决掉这种顾虑则自带了一种垃圾回收机制,从而让开发人员不必过分担心内存的使用情况而可以全身心的投入到开发中去. >>>

  • 详细分析Python可变对象和不可变对象

    在 Python 中一切都可以看作为对象.每个对象都有各自的 id, type 和 value. id: 当一个对象被创建后,它的 id 就不会在改变,这里的 id 其实就是对象在内存中的地址,可以使用 id() 去查看对象在内存中地址. type: 和 id 一样当对象呗创建之后,它的 type 也不能再被改变,type 决定了该对象所能够支持的操作 value: 对象的值 一个对象可变与否就在于 value 值是否支持改变. 不可变对象 常见的不可变对象(immutable objects)

  • 详细分析Python collections工具库

    今天为大家介绍Python当中一个很好用也是很基础的工具库,叫做collections. collection在英文当中有容器的意思,所以顾名思义,这是一个容器的集合.这个库当中的容器很多,有一些不是很常用,本篇文章选择了其中最常用的几个,一起介绍给大家. defaultdict defaultdict可以说是这个库当中使用最简单的一个,并且它的定义也很简单,我们从名称基本上就能看得出来.它解决的是我们使用dict当中最常见的问题,就是key为空的情况. 在正常情况下,我们在dict中获取元素的

  • 使用pycallgraph分析python代码函数调用流程以及框架解析

    技术背景 在上一篇博客中,我们介绍了使用量子计算模拟器ProjectQ去生成一个随机数,也介绍了随机数的应用场景等.但是有些时候我们希望可以打开这里面实现的原理,去看看在产生随机数的过程中经历了哪些运算,调用了哪些模块.只有梳理清楚这些相关的内容,我们才能够更好的使用这个产生随机数的功能.这里我们就引入一个工具pycallgraph,可以根据执行的代码,给出这些代码背后所封装和调用的所有函数.类的关系图,让我们一起来了解下这个工具的安装和使用方法. Manjaro Linux平台安装graphv

  • 分析Python感知线程状态的解决方案之Event与信号量

    目录 一.停止线程 二.线程信号的传递 三.信号量 四.总结 一.停止线程 利用Threading库我们可以很方便地创建线程,让它按照我们的想法执行我们想让它执行的事情,从而加快程序运行的效率.然而有一点坑爹的是,线程创建之后,就交给了操作系统执行,我们无法直接结束一个线程,也无法给它发送信号,无法调整它的调度,也没有其他高级操作.如果想要相关的功能,只能自己开发. 怎么开发呢? 我们创建线程的时候指定了target等于一个我们想让它执行的函数,这个函数并不一定是全局函数,实际上也可以是一个对象

  • 分析python并发网络通信模型

    目录 一.常见模型分类 1.1.循环服务器模型 1.2.IO并发模型 1.3.多进程/线程网络并发模型 二.基于fork的多进程网络并发模型 三.基于threading的多线程网络并发 四.ftp 文件服务器 4.1.项目功能 4.2.整体结构设计 五.IO并发 5.1.IO分类 5.2.IO多路复用 5.3.位运算 5.4.poll方法实现IO多路复用 5.5.epoll方法 一.常见模型分类 1.1.循环服务器模型 循环接收客户端请求,处理请求.同一时刻只能处理一个请求,处理完毕后再处理下一

  • 总结分析python数据化运营关联规则

    目录 内容介绍 一般应用场景 关联规则实现 关联规则应用举例 内容介绍 以 Python 使用 关联规则 简单举例应用关联规则分析. 关联规则 也被称为购物篮分析,用于分析数据集各项之间的关联关系. 一般应用场景 关联规则分析:最早的案例啤酒和尿布:据说是沃尔玛超市在分析顾客的购买记录时,发现许多客户购买啤酒的同时也会购买婴儿尿布,于是超市调整了啤酒和尿布的货架摆放,让这两个品类摆放在一起:结果这两个品类的销量都有明显的增长:分析原因是很多刚生小孩的男士在购买的啤酒时,会顺手带一些婴幼儿用品.

  • 回归预测分析python数据化运营线性回归总结

    目录 内容介绍 一般应用场景 线性回归的常用方法 线性回归实现 线性回归评估指标 线性回归效果可视化 数据预测 内容介绍 以 Python 使用 线性回归 简单举例应用介绍回归分析. 线性回归是利用线性的方法,模拟因变量与一个或多个自变量之间的关系: 对于模型而言,自变量是输入值,因变量是模型基于自变量的输出值,适用于x和y满足线性关系的数据类型的应用场景. 用于预测输入变量和输出变量之间的关系,特别是当输入变量的值发生变化时,输出变量的值也随之发生变化. 回归模型正是表示从输入变量到输出变量之

随机推荐