gpt4 book ai didi

python 递归函数中的生成器

转载 作者:太空宇宙 更新时间:2023-11-03 17:06:38 29 4
gpt4 key购买 nike

看了很多帖子,还是不太明白。我有以下代码,它在代码中嵌入的 sql 文本中打印出此查询的外层。

K.a
K.b
I
J
K
1
2

我不清楚递归调用函数时如何获取内层。我按照 https://github.com/andialbrecht/sqlparse/blob/master/examples/extract_table_names.py 设计了这个图案这非常相似并且有效。提前致谢。

# This example illustrates how to extract table names from nested
# SELECT statements.

# See:
# http://groups.google.com/group/sqlparse/browse_thread/thread/b0bd9a022e9d4895

sql = """
select K.a,K.b from (select H.b from (select G.c from (select F.d from
(select E.e from A, B, C, D, E), F), G), H), I, J, K order by 1,2;
"""
import sqlparse
from sqlparse.sql import IdentifierList, Identifier
from sqlparse.tokens import Keyword, DML


def is_subselect(parsed):
if not parsed.is_group():
return False
for item in parsed.tokens:
if item.ttype is DML and item.value.upper() == 'SELECT':
return True
return False


def extract_from_part(parsed):
from_seen = False
for item in parsed.tokens:
if item.ttype is Keyword:
lastKeyword = str(item)
#if from_seen:
if is_subselect(item):
for x in extract_from_part(item):
if type(item) in(sqlparse.sql.IdentifierList,sqlparse.sql.Identifier):
yield x
else:
if type(item) in( sqlparse.sql.IdentifierList,sqlparse.sql.Identifier):
yield item

def extract_table_identifiers(token_stream):
for item in token_stream:
if isinstance(item, IdentifierList):
for identifier in item.get_identifiers():
yield str(identifier)
elif isinstance(item, Identifier):
#yield item.get_name()
yield str(identifier)
# It's a bug to check for Keyword here, but in the example
# above some tables names are identified as keywords...
elif item.ttype is Keyword:
yield item.value

def extract_tables():
stream = extract_from_part(sqlparse.parse(sql)[0])
return list(extract_table_identifiers(stream))
#return stream


if __name__ == '__main__':
#print('Tables: %s' % ', '.join(extract_tables()))
ids = extract_tables()
for x in ids:
print x

最佳答案

您在递归调用后的循环中执行的类型检查测试了错误的对象类型:

    if is_subselect(item):
for x in extract_from_part(item):
# next line should check type(x) rather than type(item)
if type(item) in(sqlparse.sql.IdentifierList,sqlparse.sql.Identifier):
yield x

尽管如此,类型检查是不必要的,因为非递归情况只会产生 IdentifierIdentifierList 项。因此,只需删除该行(并取消缩进以下 yield)即可。

虽然这不是此问题的原因,但我还建议使用 isinstance 而不是直接比较类型:

if isinstance(item, (sqlparse.sql.Identifier, sqlparse.sql.IdentifierList)):
yield item

关于python 递归函数中的生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34521033/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com