2016-11-27 2 views
3

В некотором быстром контексте я использую текстовый редактор Vim и с ним - плагин под названием UltiSnips. У меня иногда есть строки, подобные этому в моем коде, где у меня есть словарь, который использует более одного ключа в одной строке.Разделите строку кода Python на свои части

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, но он оказался более сложным, чем я Тхо Потому что аш оценивает назад от того, как я ожидал. Я пишу, чтобы спросить, есть ли что-то вроде этого, которое существует или, возможно, лучший способ приблизиться к этой проблеме.

Образец набора для тестирования раствора (верхняя строка ввода, печатные линии ожидаемый выход):

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()) 

я выложу свое собственное решение позже, когда у меня есть больше времени для работы над это

+4

Вы могли бы взглянуть на 'pyparsing'. Пример: 'import pyparsing ne = pyparsing.nestedExpr (opener = '[', closer = ']', content = 'someDict [" something "] [some_module.someOtherDict [" somethingElse "]]')' –

+0

Никогда не слышал этого модуля, пока вы не упомянете об этом. Это выглядит супер полезно, спасибо за обмен! – ColinKennedy

ответ

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"]]) 
Смежные вопросы