初学 python的 with 和 yield

本文介绍了Python中的两个重要关键字`with`和`yield`。`yield`用于创建生成器,允许函数在每次迭代时返回一个值,而不需要保存所有状态。`with`关键字通常用于简化资源管理,如文件操作,确保即使在异常情况下也能正确关闭资源。通过`__enter__`和`__exit__`方法,`with`语句提供了优雅的错误处理和资源清理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不久前面试时候面试官提起了python的这两个关键字,问我了解过没有,我当时没能答上来,接触python时间太短,虽然只是随口一问,我还是随后查资料。

yield

找到了一篇关于yield的神文:(译)Python关键字yield的解释(stackoverflow)
这篇文章翻译自 stackoverflow 上一篇帖子,介绍的非常详细了,yield返回的就是生成器,“生成器是可以迭代的,但是你 只可以读取它一次 ,因为它并不把所有的值放在内存中,它是实时地生成数据。”
我写的是我读后总结,所以有不够详尽的地方,建议直接阅读上面的文章。
for … in … 是一个迭代器,他可以遍历迭代的内容。

index = (x+x for x in range(3)) # 这是一个生成器
for i in range(index):
	print(i)
	
for i in range(index): # 执行程序,你会发现,第二次根本没有打印出数据
	print(i)

输出内容:可以看到只有一次输出

0
2
4

yield 生成器举例:

class test()
	def testYield()
		for i in range(3):
			yield i

t = test()
index = t.testYield()
for i in index:
	print(i)
	
index = t.testYield()
for i in index:
	print(i)

输出内容:可以看到,重新调用生成器方法后,就可以再进行读取了。

0
1
2
0
1
2

我因为没有python的项目经验,所以对yield的具体理解只能到此为止。

with

之前编写批量修改文件的时候有用到过,记忆不深,在这里再强化一下。
with经常适用于try except finally 的优化,当然,with适用的范围不止是try catch。

fileName = "server.log"
# 读取文件
f = open(fileName, 'r')
try:
	e = f.read()
except:
	pass
finally:
	f.close()

# 上面代码等同于
with open(fileName) as f:
	f.read()

用with更加简洁美观,而且就算发生异常,也会执行完毕f.close()。

with的原理是,with后代码返回的对象需包含 __enter__() 和 __exit__() 的方法,先执行 __enter__() ,然后执行代码块,将返回值赋给 as 后面的变量在内容中使用,然后执行内容,结束或者发生异常会先调用代码块的 __exit__() 。结合这个,可以设计出适用with的代码结构。

class test():
    def __enter__(self):
        print("1.enter")
        return self
    def __exit__(self, etype, evalue, etraceback):
        print("type is %s" % etype)
        print("type is %s" % evalue)
        print("type is %s" % etraceback)
        print("3.exit")
    def t(self):
        x = 1/0
        print("2.test" + x)

with test() as t:
	t.t()

输出:可见,在异常被捕捉前,__exit__()执行完毕。

1.enter
type is <type 'exceptions.ZeroDivisionError'>
type is integer division or modulo by zero
type is <traceback object at 0x10314aea8>
3.exit
Traceback (most recent call last):
  File "test.py", line 17, in <module>
    t.t()
  File "test.py", line 13, in t
    x = 1/0
ZeroDivisionError: integer division or modulo by zero
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值