前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >matinal:python 部分内置函数详解

matinal:python 部分内置函数详解

作者头像
matinal
发布2023-10-14 14:11:17
1920
发布2023-10-14 14:11:17
举报
文章被收录于专栏:SAP TechnicalSAP Technical

eval与exec

evalexec都是python内置的可以执行python代码的函数,但它们之间有所区别。

  • eval(expression[, globals[, locals]]) expression:需要执行的python表达式 globals:需要注入的全局变量,必须为字典 locals:需要注入的局部对象 需要注意的是对于闭包中的嵌套作用域无法获取 eval会返回表达式的执行结果
代码语言:javascript
复制
a = 1
command = "a > 2"
print(eval(command))
print(eval("b + 1", {"b": 1}))
代码语言:javascript
复制
False
2
需要注意的是eval可能存在类似于SQL注入的风险,下面将对其进行描述
代码语言:javascript
复制
while True:
    string_data = input("请输入一段文字:")
    print(eval(string_data))

上述代码含义就是输出用户输入的内容并使用eval返回相应结果。 正常情况下,输入相应内容会输出相应结果, 异常情况,当输入__import__("os").system("dir")时,我们可以看到eval执行了相应的结果,返回了对应的结果,上述指令的含义为执行相应的指令,因此当我们将命令换成删除等动作时将会造成无法挽回的后果,类似于SQL注入,因此对于进行eval执行表达式获取结果时需要注意此类问题。

  • exec(object[, globals[, locals]]) object:需要执行的python代码,可以是代码对象 globals:需要注入的全局变量,必须为字典 locals:需要注入的局部对象 exec支持动态执行python代码,如果是字符串则解析称python代码执行
代码语言:javascript
复制
command = "a = 2"
print(exec(command))
print(a)

print(globals())
print(locals())
代码语言:javascript
复制
None
2
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000027E90174A30>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 
'builtins' (built-in)>, '__file__': 'd:\\python_study\\study\\2022_7_25\\test.py', '__cached__': None, 'a': 2, 'command': 'a = 2'}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000027E90174A30>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 
'builtins' (built-in)>, '__file__': 'd:\\python_study\\study\\2022_7_25\\test.py', '__cached__': None, 'a': 2, 'command': 'a = 2'}

globals()locals()分别是查看全局命名空间和局部命名空间的内置函数。

由于exec与eval类似并且可以执行任意合法代码,因此也会存在注入问题,与上述eval执行相应命令类似,执行相应命令时会存在风险。

区别

eval

exec

执行内容

只能是表达式之类的,无法使用赋值、声明变量等

任意合法的python代码即可

返回值

返回的是表达式的执行结果

返回均为None

声明的globals外界是否可用

不可用,只能在eval内部使用

不可用,只能在exec内部使用

iter(object[, sentinel])

返回一个迭代器

  • object:需要操作的对象,对象要求跟随是否存在第二个参数来决定
  • sentinel:需要标记的返回值,正常都是设置为b'' 1.当不存在第二个参数时,object必须时可迭代对象(包含__iter__方法)或者必须支持序列协议(有 __getitem__() 方法,且数字参数从 0 开始, 2.当存在第二个参数时,每次迭代调用它的__next__() 方法时都会不带实参地调用 object;如果返回的结果是 sentinel 则触发 StopIteration,否则返回调用结果。 3.适合 iter() 的第二种形式的应用之一是构建块读取器。 例如,从二进制数据库文件中读取固定宽度的块,直至到达文件的末尾:
代码语言:javascript
复制
from functools import partial
with open('mydata.db', 'rb') as f:
    for block in iter(partial(f.read, 64), b''):
        process_block(block)

当iter有了第二个参数后,可以将方法函数等转变为迭代器,正常第二个参数改变b''

代码语言:javascript
复制
def fun(number):
    return number + 1

from typing import Iterator

fun2 = lambda: fun(1)
print(type(fun2))
data = iter(fun2, b'')
print(type(data))
print(isinstance(data, Iterator))
代码语言:javascript
复制
<class 'function'>
<class 'callable_iterator'>    
True

iter可以替代while的无限循环,例如读取socket的io流,以及读取文件等

代码语言:javascript
复制
from pathlib import Path
from functools import partial


file_path = Path(__file__).parent.joinpath("05使用语法.py")

with open(file_path, "r", encoding="utf-8") as f:
    while True:
        line = f.readline()
        print(line)
        if not line:
            break

with open(file_path, "r", encoding="utf-8") as f:
    for line in iter(lambda: f.readline(), b''):
        print(line)
        if not line:
            break

当设置了__sentinel之后,将会在迭代过程中遇到__sentinel将会自动触发stopIteration停止迭代。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • eval与exec
    • 需要注意的是eval可能存在类似于SQL注入的风险,下面将对其进行描述
      • 由于exec与eval类似并且可以执行任意合法代码,因此也会存在注入问题,与上述eval执行相应命令类似,执行相应命令时会存在风险。
      • iter(object[, sentinel])
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档