问题描述
我写了Flake8-simplify
(PyPI,GitHub),这是一个Flake8插件,可以找到可以简化的代码。
我要找到的一种模式是:
# Bad
for x in iterable:
if check(x):
return True
return False
# Good
return any(check(x) for x in iterable)
“不良”部分的AST如下:
[
For(
target=Name(id='x',ctx=Store()),iter=Name(id='iterable',ctx=Load()),body=[
If(
test=Call(
func=Name(id='check',args=[Name(id='x',ctx=Load())],keywords=[],),body=[
Return(
value=Constant(value=True,kind=None),],orelse=[],type_comment=None,Return(
value=Constant(value=False,]
这里的问题是我需要检查For
和 Return
。 **在给定Python ast.For
节点的情况下,如何获得下一个(同级)节点?
我尝试过的
import ast
from typing import List,Tuple
SIM110 = "SIM110 Use 'return any({check} for {target} in {iterable})'"
class Visitor(ast.NodeVisitor):
def visit_For(self,node: ast.For) -> None:
self.errors += _get_sim110(node)
self.generic_visit(node)
def _get_sim110(node: ast.ForOp) -> List[Tuple[int,int,str]]:
errors: List[Tuple[int,str]] = []
if not (
len(node.body) == 1
and isinstance(node.body[0],ast.If)
and len(node.body[0].body) == 1
and isinstance(node.body[0].body[0],ast.Return)
and node.body[0].body[0].value is True
and [Todo: after the For loop is a "return False"]
):
return errors
# Prepare the message
check = to_source(node.body[0].test)
target = to_source(node.target)
iterable = to_source(node.iter)
errors.append(
(
node.lineno,node.col_offset,SIM110.format(check=check,target=target,iterable=iterable),)
)
return errors
def to_source(node: ast.expr) -> str:
import astor
source = astor.to_source(node).strip()
return source
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)