Могу ли я использовать модуль python ast для этого? - PullRequest
1 голос
/ 18 июня 2010

Я хотел бы написать программу, которая изменяет программы на Python следующим образом:

изменить

"некоторая буквенная строка%"% SOMETHING

на

functioncall ("некоторая буквенная строка%")% SOMETHING

Спасибо,

Ответы [ 4 ]

2 голосов
/ 18 июня 2010

Может быть проще с tokenize - адаптируя пример в документах,

import cStringIO
import tokenize

class Lookahead(object):

  def __init__(self, s):
    self._t = tokenize.generate_tokens(cStringIO.StringIO(s).readline)
    self.lookahead = next(self._t, None)

  def __iter__(self):
    return self

  def next(self):
    result = self.lookahead
    if result is None: raise StopIteration
    self.lookahead = next(self._t, None)
    return result


def doit(s):
  toks = Lookahead(s)
  result = []
  for toktype, tokvalue, _, _, _ in toks:
    if toktype == tokenize.STRING:
      pk = toks.lookahead
      if pk is not None and pk[0] == tokenize.OP and pk[1] == '%':
        result.extend([
            (tokenize.NAME, 'functioncall'),
            (tokenize.OP, '('),
            (tokenize.STRING, repr(tokvalue)),
            (tokenize.OP, ')')
        ])
        continue
    result.append((toktype, tokvalue))
  return tokenize.untokenize(result)


print doit('"some literal string %" % SOMETHING')

Это печатает functioncall ('"some literal string %"')%SOMETHING.Интервал довольно своеобразен (требуется гораздо больше усилий, чтобы получить правильный интервал - но это еще хуже для восстановления источников из модифицированного AST), но это просто хорошо, если все, что вы собираетесь сделать, это импортировать / запуститьрезультирующий код (не очень хорошо, если вы хотите получить хорошо читаемый и редактируемый код - но это достаточно большая проблема, поэтому я бы предложил отдельный Q; -).

1 голос
/ 18 июня 2010

Вы можете решить эту проблему, написав программу. Вместо этого просто используйте лучший из когда-либо созданных редакторов: Emacs. Стоит учиться, если вы еще этого не сделали. С его помощью вы можете решить эту проблему, используя возможность регулярного замены. Единственная проблема заключается в том, что я редко использую регулярные выражения, поэтому я всегда забываю детали загадочного синтаксиса и все равно вынужден искать его: P Я попытаюсь выяснить это снова для вас. Вот ссылка на Поиск и замена информации для Emacs - прокрутите вниз для использования регулярных выражений

0 голосов
/ 18 июня 2010
import re

pattern = r'(".+? %")(?= %)'
oldstr = '"some literal string %" % SOMETHING'

newstr = re.sub(pattern, r'functioncall(\1)', oldstr)

Попробуйте что-нибудь подобное.(Хотя с файловым вводом / выводом, конечно.) Я еще не работал с ast, поэтому я не знаю, будет ли проще использовать это для чего-то подобного, но мне кажется, чтоесли вы просто выполняете простой поиск-замену и не выполняете много сложного анализа, тогда нет необходимости использовать ast.

0 голосов
/ 18 июня 2010

Здесь - еще один вопрос, который может быть полезен.

Я понял, что в модуле ast нет возможности возврата к исходному коду, но Армин Ронахер написалмодуль codegen , который реализует функцию to_source для выполнения этой операции для ast узлов.

Я не пытался сделать это сам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...