使用python的生成器函数
我在python中练习使用生成器函数,因此我定义了一个函数,如下所示:使用python的生成器函数,python,generator,Python,Generator,我在python中练习使用生成器函数,因此我定义了一个函数,如下所示: def MySQL_product(): #Establish connection to database try: connection = msql.connect(host = 'localhost', user = 'max', passwd = 'password', db = 'schools') except: pass #Iterate through
def MySQL_product():
#Establish connection to database
try:
connection = msql.connect(host = 'localhost', user = 'max', passwd = 'password', db = 'schools')
except:
pass
#Iterate through each product and insert them in database
with connection:
cursor = connection.cursor()
cursor.execute("SELECT name, age, gender, school
WHERE GroupId = 'student' AND Exchange = 'foreign'")
for product in cursor.fetchall():
yield product
def main():
for column in range (0, number_of_schools):
for product in MySQL_product():
print product
但是,当我运行这段代码时,我看到的所有输出都是
generator object at…
我正试图打印在数据库中找到的内容。另外,MySQL\u product()
中的print
语句也不会执行。生成器的要点是,它不应该返回数据库中所有行的列表,而应该逐个返回。然后我想访问/打印这些项目。如何修复此代码?我的第一个答案不正确,其他人已经给出了最佳解决方案,因此我将说明替代方案和潜在用例。如果您需要在生成器上一次迭代两个项目,或者以任何其他自定义方式迭代,那么next
方法可能会很有用
def gen():
for i in range(20):
yield i
for i in gen():
print "Center", str(i).center(10)
a = gen()
for i in range(10):
left = str(a.next()).ljust(10)
right = str(a.next()).rjust(10)
如果您正在执行cursor.fetchall(),这意味着您正在将SQL server中的所有可用结果复制到python内存中。因此,在这种情况下,生成器不能为您提供任何信息 如果改为使用cursor.fetchmany()或cursor.fetchone(),您将看到的唯一好处是Python方面的内存消耗,因为您一次只能处理“一些”或“一个”结果。在SQL端,服务器仍将缓存该结果集(烧掉SQL服务器上的宝贵资源) 但是,最终——如果您确实以块的形式处理结果——因为您将处于以下循环中:
while there_are_more_results:
results = cursor.fetchmany(10)
for result in results:
do_something(result)
拥有一个生成器不会给您带来任何真正的好处,因为您必须在从mysql获得更多结果时进行阻塞
不过,我想回答你的问题
要使代码正常工作,您需要做的是:
def main():
for column in range (0, number_of_schools):
for student in MySQL_product():
print student
当你异步工作时,生成器真的很有用——基本上是在生成器还没有准备好的情况下——你只需跳过它,让其他东西工作即可 是的,这就是生成器的行为-它总是返回一个迭代器,然后您可以使用它,例如
for
语句。您可能希望将main()
函数更改为如下内容:
def main():
for column in range (0, number_of_schools):
for student in MySQL_product():
print student
也可以通过函数获得迭代器生成的下一个结果,但通常您更喜欢使用迭代器中的项直接进行迭代:#…(因为您的代码更容易阅读,并且在执行类似于从生成器函数切换回返回列表的常规函数的操作时更不脆弱)。print students.next()将只打印一个结果。您必须迭代生成器。my
MySQL\U product()如何
函数,我是否要更改fetchall()
?@MaxKim不知道;我没有查看您的MySQL\u product()
函数内部…但是@synthezerpatel似乎已经涵盖了您。我也要将MySQL\u product()
中的fetchall()
更改为fetchone()
当我执行你的main
时?一次获取一个结果会非常慢,最佳大小取决于你的mysql服务器是如何调整的。尝试256作为起点。我不确定我是否遵循了你的意思,你能看一下编辑的问题吗?如果我理解你的意思,生成器在是问题吗?生成器对于您问题的根本所在的特定任务可能不是必需的,也不是有益的。如果您使用的是像umysql这样的异步MySQL驱动程序,您至少会获得这样的好处:在大型选择中,您不会被锁定在读取()中当您必须处理结果时,您可以在从mysql服务器读取结果、迭代一个将结果块传递回的生成器以及最终对每个结果执行操作之间来回切换。