怎么理解python中的关键字yield

本文围绕Scrapy中的生成器(yield)展开。作者起初对生成器理解不深,后在工作中体会到其好用之处。通过生成大量数字、数据库翻页查询等场景,说明使用生成器可避免内存占用过大,能按规则在需要时生成数据,实现边查边用。

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

用过scrapy的同学都知道,scrapy中会出现yield这个关键字。开始的时候我其实我知道他是生成器的一种标志,但并不能深刻的理解这个东西。在工作中的一些场景中我深刻的体会到了生成器的好用之处。
首先我举一些应用场景来帮助大家理解为何我们要使用这个生成器。假如现在我们需要生成1到100的数字。我们很容易想到用列表推导式。

numbers = [i for i in range(1,101)]
print(numbers)

试想下如果我们要生成的数值很多时,当我们还用列表推导式或者循环生成的话,是不是这些数值占用了很大的内存呢?有没有一种方式我们定义好要生成的规则,当我们需要的时候我们在生成呢?

numbers = (i for i in range(1,101))
print(numbers)
print(next(numbers))
for i in numbers:
    print(i)

numbers是一个生成器,定义了我们生成100个数的规则,next()函数执行取出数值。生成器是一个可迭代的对象。通过循环可以取出数值。for 循环就相当于next()函数的功能。
用yield可以这么写:

def get_num():
    for i in range(100):
        yield i
a = get_num()
for i in a:
    print(i)

在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

再举个例子,比如现在有个需求需要查询数据库表中的数据。但是数据很多,需要设计翻页查询。但是如果数据非常多,该怎么设计才合理呢?不可能一直循环然后查完,再拿来用吧。很理想的是查一点用一点,边查边用。这边这样设计,假设每次查100条数据。通过定义生成器的规则来实现

def get_data():
	limit=100, offset=0
	 while True:
	        query_sql = '''
	      
	        '''
	        conn = pymysql.connect(host=MYSQL_HOST, port=MYSQL_PORT, user=MYSQL_USER_NAME, passwd=MYSQL_PASSWORD,
	                               db="", charset='UTF8')
	        cursor = conn.cursor()
	        try:
	            cursor.execute(query_sql % (limit, offset))
	            result = cursor.fetchall()
	            if not result:
	                break
	            offset += limit
	            # result双重tuple转成list
	            result_list = []
	            for tuple_single in result:
	                result_list.append(tuple_single[0])
	            logging.info(f"")
	            yield result_list
	        except Exception as ex:
	            logging.info(f"查询失败,原因: {ex}")
	        finally:
	            cursor.close()  # 关闭游标
	            conn.close()  # 释放数据库资源

get_data就是定义的一个生成器。这样我们就能循环这个生成器来获取数据了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值