Python 特性总结

随着项目越来越大, 功能越来越多, 使用python特性的地方也越来越多,随着对python特性的使用, 对这些概念的理解也越来越深, 因此写此文打卡

文章目录

  • 迭代器
  • 生成器
  • 装饰器
  • 上下文管理器

迭代器

背景: 序列中元素的迭代操作十分频繁, 而python中大部分的数据结构都是序列, 因此python提供了额外的工具来使迭代操作简单、高效; 这种工具就是迭代器

迭代器相关概念

迭代: 重复相同的动作
可迭代:实现了__iter__()方法的对象都是可迭代的。通过isinstance()可判断一个对象是否可迭代, 如case 1.1isinstance(owef(), collections.Iterable)判断是否可迭代

1
2
3
4
5
6
7
8
9
import collections

class owef:
def __iter__(self):
pass

print(isinstance(owef(), collections.Iterable))

# Ans: True

迭代器:

  • python2: 实现了next()方法且可以无参数调用的对象是迭代器
  • python3: 实现了__next__()方法且可无参数调用的对象是一个迭代器
    反向迭代器: 实现了__reversed__方法的迭代器称为反向迭代器
    迭代协议: 同时实现__iter__()、__next__()方法的对象实现了迭代协议, 可被for循环调用

内置类型迭代器

  • 文件迭代器

迭代器的优点

快速, 迭代器在python中是以C语言运行的速度来运行的, 而普通的for、while循环均为python运行速度来运行, 理论上来说迭代器的运行速度更快但是也不尽然, 在是实际环境中需要通过计时操作判断哪一种方式更加快速;

可被for循环调用的对象必须实现迭代协议, for循环时, 先调用被循环对象的iter方法获取一个可迭代的对象, 然后可迭代的对象不停调用next()方法来获取新的数据

生成器

生成器是封装后的迭代器, 比迭代器功能强大。

生成器相关概念

生成器: 含有yield的函数或对象被称为生成器

生成器的函数

__del__()__getattribute__(self, name, /)__iter__(self, /)__next__(self, /)__repr__(self, /)close()send(arg)throw()

  1. 调用生成器时, 生成器将返回一个迭代器
  2. 可通过生成器的sned(arg)方法与生成器通信, 协程便是利用此方法实现; 当外部调用生成器的send(arg)方法时, 将唤醒生成器, 生成器内部通过arg = yield r的形式接收外部发送的数据并存入局部变量arg中, 然后调用内部迭代器的next方法返回一个数据, 然后睡眠。
  3. 创建迭代器的最佳方案是使用生成器创建

装饰器

上下文管理器

上下文管理器主要用来处理加载需要释放的资源的问题。

概念的理解

case 1: python中的上下文

1
2
3
4
5
a = 2
print(a)

b = 3
print(b)

python是解释型语言, 代码是从上向下逐条运行的, 在case 1中, print(a)的上下文分别是该条语句上下的哪些代码;

case 2: 语句附近的上下文

1
2
3
4
5
6
7
8
f_user = open("user.txt")
f_pass = open("passwd.txt")
for u in f_user:
for p in f_pass:
print(u.strip(), p.strip())

f_user.close()
f_pass.close()

上下文管理器中的上下文: 当通过文件对象读取文件时, 需要先创建文件文件对象, 读取之后需要关闭文件对象; 这些代码在python中可以放在文件对象读取数据的上下, 如:case 2; 也可以放在遥远的上下, 如: case 3; 这些都可以叫做文件对象读取文件的上下文, 上下文管理器中的上下文就是特指这种需要先创建对象, 使用完对象之后需要进行资源释放和回收的上下文环境。

case 3: 遥远的上下文

1
2
3
4
5
6
7
8
9
10
11
12
13
f_user = open("user.txt")
f_pass = open("passwd.txt")

...好多语句

for u in f_user:
for p in f_pass:
print(u, p)

...好多语句

f_user.close()
f_pass.close()

case 4: 上下文协议

1
2
3
4
5
6
7
8
9
10
11
12
# 上下文管理器
class Contextor:
def __enter__(self):
print("welcome to contextor")
def __exit__(self, exc_type, exc_val, exc_tb):
print("goodbye.")

contextor = Contextor()

# 调用上下文管理器
with contextor as c:
print("i use a contextor.")

上下文协议:实现了enter()、exit()方法的对象, 实现了上下文协议, with语句调用的对象必须实现上下文协议。

with与上下文管理器

with语句用于上下文管理器的调用, 旨在简化”上下文管理”的重复代码; 可以使用with的语句的对象都是上下文管理器对象, 均实现了上下文管理协议.

case 5: with与上下文管理器

1
2
3
4
5
6
7
8
9
with open("file1.txt") as f:
print(f.readlines())
'''
with语句的执行过程分为四步:
1. 执行with后的语句获得一个匿名对象lambda_f;
2. 调用lambda_f的__enter__()方法, 返回一个文件操作对象lambda_file并赋值给f;
3. 执行pring(f.readlines())
4. 调用f的__exit__()方法关闭文件操作对象
'''

通过with语句调用open()方法时, open("file1.txt")会返回一个匿名对象, 记为lambda_f; with语句调用lambda_f的__enter__()方法, 该方法将返回一个新的对象lambda_file并赋值给as声明的变量f;

case 6: with与自建上下文管理器

1
2
3
4
5
6
7
8
9
10
class Contextor:
def __enter__(self):
print("welcome to contextor")
def __exit__(self, exc_type, exc_val, exc_tb):
print("goodbye.")

contextor = Contextor()

with contextor as c:
print("i use a contextor.")

通过case 6的结果, 我们将更了解with与上下文管理器之间的运行原理, 结果如下:

owefsad wechat
进击的DevSecOps,持续分享SAST/IAST/RASP的技术原理及甲方落地实践。如果你对 SAST、IAST、RASP方向感兴趣,可以扫描下方二维码关注公众号,获得更及时的内容推送。
0%