将一行Python代码划分为其部分

时间:2016-11-27 20:46:39

标签: python abstract-syntax-tree

一些快速上下文,我使用Vim文本编辑器和它,一个名为UltiSnips的插件。我有时在我的代码中有这样的行,我有一个字典,它在一行中使用了多个键。

someDict["something"]["anotherThing"]

如果此行获得KeyError,我选择该行并使用UltiSnips插件将其转换为其部分。

print(someDict)
print(someDict["something"])
print(someDict["something"]["anotherThing"])

它适用于简单的目的,但我希望它更加智能,因为目前我无法处理任何更复杂的事情,比如

someDict["something"][some_module.someOtherDict["somethingElse"]]

(预期产出)

print(someDict)
print(someDict["something"])
print(some_module)
print(some_module.someOtherDict)
print(some_module.someOtherDict["somethingElse"])
print(someDict["something"][some_module.someOtherDict["somethingElse"]])

我正在考虑从我当前的系统切换到捕获[] s的正则表达式,使用Python的ast模块处理该行,但事实证明它比我想象的更复杂,因为ast会从方式向后评估我原以为是。我正在写信询问是否存在类似的东西,或者是解决这个问题的更好方法。

用于测试解决方案的样本集(输入顶行,打印行是预期输出):

something
print(something)

something.anotherThing
print(something)
print(something.anotherThing)

something.anotherThing()
print(something)
print(something.anotherThing)
print(something.anotherThing())

something.anotherThing()['aDictKey'].moreMethods(valueInfo, 8, 'methodString', someKeyword=value, *args, **kwargs)
print(something)
print(something.anotherThing)
print(something.anotherThing())
print('aDictKey')
print(something.anotherThing()['aDictKey'])
print(something.anotherThing()['aDictKey'].moreMethods)
print(valueInfo)
print(8)
print('methodStrings')
print(value)
print(*args)
print(**kwargs)
print(valueInfo, 8, 'methodString', someKeyword=value, *args, **kwargs)
print(something.anotherThing()['aDictKey'].moreMethods(valueInfo, 8, 'methodString', someKeyword=value, *args, **kwargs))

something.anotherThing()[(someObj.someDict['itsKey'], 8, True)].moreMethods()
print(something)
print(something.anotherThing)
print(something.anotherThing())
print(someObj)
print(someObj.someDict)
print('itsKey')
print(someObj.someDict['itsKey'])
print(8)
print(True)
print(something.anotherThing()[someObj.someDict['itsKey']])
print(something.anotherThing()[someObj.someDict['itsKey']].moreMethods)
print(something.anotherThing()[someObj.someDict['itsKey']].moreMethods())

稍后当我有更多时间来处理这个

时,我会发布我自己的解决方案

1 个答案:

答案 0 :(得分:1)

以下是使用ASTTokens的解决方案:

import ast, asttokens

def expand(line):
  atok = asttokens.ASTTokens(line, parse=True)
  return [atok.get_text(n) for n in ast.walk(atok.tree)
          if isinstance(n, ast.expr) and not isinstance(n, (ast.Num, ast.Str))]

for expr in reversed(expand('someDict["something"][some_module.someOtherDict["somethingElse"]]')):
  print("print(%s)" % expr)

输出:

print(some_module)
print(some_module.someOtherDict)
print(some_module.someOtherDict["somethingElse"])
print(someDict)
print(someDict["something"])
print(someDict["something"][some_module.someOtherDict["somethingElse"]])