将一行 Python 代码分成几个部分
Divide a line of Python code into its parts
一些快速上下文,我使用 Vim 文本编辑器和一个名为 UltiSnips 的插件。我的代码中有时会有这样的行,其中我有一本字典,在一行中使用多个键。
someDict["something"]["anotherThing"]
如果此行出现 KeyError,我 select 该行并使用 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"]])
我正在考虑从我当前的系统(只是捕获 [] 的正则表达式)切换到使用 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())
当我有更多时间处理这个问题时,我会post我自己的解决方案
这是一个使用 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"]])
一些快速上下文,我使用 Vim 文本编辑器和一个名为 UltiSnips 的插件。我的代码中有时会有这样的行,其中我有一本字典,在一行中使用多个键。
someDict["something"]["anotherThing"]
如果此行出现 KeyError,我 select 该行并使用 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"]])
我正在考虑从我当前的系统(只是捕获 [] 的正则表达式)切换到使用 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())
当我有更多时间处理这个问题时,我会post我自己的解决方案
这是一个使用 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"]])