Nano Hash - криптовалюты, майнинг, программирование

Как разобрать циклы Python с помощью скрипта Python?

Моя основная цель - разобрать циклы Python, чтобы я мог вставить несколько операторов для своего анализа.

Normal code:
#A.py

[code Starts]
.
.
.
while [condition]:
    [statements]
    [statements]
    [statements]

.
.
.
[code ends]

Инструментальный код:

Normal code:
#A.py

[code Starts]
.
.
.
count =0                                    <---------- inserted code 
print "Entry of loop"                       <---------- inserted code
while [condition]:
    print "Iteration Number " + count++     <---------- inserted code
    [statements]
    [statements]
    [statements]
print "Exit of loop"                        <---------- inserted code
.
.
.
[code ends]

Моя цель - вставить приведенные выше коды в соответствующие места с правильным отступом. Цикл также может быть циклом for. Чтобы получить приведенный выше инструментальный код, мне нужно проанализировать циклы в файле A.py и вставить этот код.

Есть ли хороший способ проанализировать эти циклы и получить номер строки цикла, чтобы я мог использовать инструмент?

Спасибо


  • Вы пытались сделать это с помощью модуля ast? Эта задача очень похожа на ваш предыдущий вопрос. 11.06.2013
  • @Janne Karila Да, мне действительно нужно точно так же, как в последнем вопросе. Но так как я никогда не использовал ast, я не знаю, какую функцию использовать. Было бы любезно с вашей стороны, если бы вы могли просто опубликовать простой сценарий? 11.06.2013
  • Предполагая, что вы проанализируете файл, как вы определите, какой цикл нужно инструментировать, или вы инструментируете их все? 11.06.2013
  • @chepner я бы все инструменты. Это мое требование 11.06.2013
  • Вы хотите только циклы на уровне модуля? например в if some condition: for elem in iterable: do stuff вы хотите добавить код для внутреннего for? Вы не возражаете против вложенных циклов? Вы хотите обрабатывать однострочные циклы (например, for x in a: print x)? В простейшем случае должно быть довольно легко просто прочитать файл построчно и вывести дополнительные строки, когда это необходимо, в противном случае вам придется выполнять дополнительный синтаксический анализ. 11.06.2013

Ответы:


1

Разбор обычно представляет собой сложную задачу. Вы можете использовать библиотеку Python Pygments, которая представляет собой библиотеку подсветки синтаксиса. Это может показаться отличным от того, что вы собираетесь делать, но это не так. В конце концов, раскрашивающий код в основном добавляет информацию о цвете к блокам кода.

Используя PythonLexer, вы можете извлекать токены для каждой строки и добавлять любые комментарии. Это пригодится, если вы хотите работать не только с циклами while, но и с циклами for, операторы if...

11.06.2013

2

pyparsing содержит образец файла, содержащий полный (?) анализатор грамматики Python. В долгосрочной перспективе это может быть интересным вариантом, особенно если/когда ваш проект анализа получит больше возможностей:

11.06.2013
  • Pyparsing больше не размещается на wikispaces.com. Перейдите на страницу github.com/pyparsing/pyparsing. 27.08.2018

  • 3

    Самый простой способ сделать это — просто просмотреть файл построчно и добавить операторы, когда вы найдете подходящую строку.

    Следующий код делает то, что вы хотите, но он ненадежен вообще:

    def add_info_on_loops(iterable):
        in_loop = False
        for line in iterable:
            if not in_loop:
                if line.startswith('for ') or line.startswith('while '):
                    in_loop = True
                    yield 'count = 0\n'
                    yield 'print "Entry of loop"\n'
                    yield line
                    yield '    print "Iteration Number:", count'
                    yield '    count += 1\n'
                else:
                    yield line
            else:
                if not line.startswith('    '):
                    in_loop = False
                    yield 'print "Exit of loop"\n'
                yield line
    

    Применение:

    >>> code = StringIO("""[code Starts]
    ... .
    ... .
    ... .
    ... while [condition]:
    ...     [statements]
    ...     [statements]
    ...     [statements]
    ... 
    ... .
    ... .
    ... .
    ... [code ends]""")
    >>> print ''.join(add_info_on_loops(code))
    [code Starts]
    .
    .
    .
    count = 0
    print "Entry of loop"
    while [condition]:
        print "Iteration Number:", count    count += 1
        [statements]
        [statements]
        [statements]
    print "Exit of loop"
    
    .
    .
    .
    [code ends]
    

    Подводные камни кода:

    1. Код обрабатывает только циклы на верхнем уровне. Что-то вроде if condition: for x in a: ... не распознается. Это можно решить, удалив строки пробелов перед проверкой, есть ли у нас цикл или нет (но тогда вы должны учитывать различные уровни отступов и т. д.)
    2. Код прерывается всякий раз, когда в цикле есть строка без отступа. Это произойдет, например, если вы «разделите» код пустой строкой, а IDE удалит пробелы. Решением может быть ожидание непустой строки без отступа вместо строки без отступа.
    3. Код не обрабатывает вкладки для отступов (легко исправлено)
    4. Код не обрабатывает однострочные циклы (например, for x in a: print x). В этом случае вы получите неправильный вывод. Легко исправлена ​​проверка, есть ли что-то после :.
    5. Использование одной переменной count проблематично, если вы хотите добавить поддержку вложенных циклов. Вероятно, вам следует где-то иметь целочисленный идентификатор и использовать имена переменных, такие как count_0, count_1, с идентификатором, который увеличивается каждый раз, когда вы находите новый цикл.
    6. Код не обрабатывает выражения со скобками, в которых нет пробелов с клавиатуры. например for(a,b) in x: не определяется как петля, а for (a,b) in x: определяется. Это можно легко решить. Сначала вы проверяете, начинается ли строка с for и while, а следующий символ не должен быть буквой, цифрой, символом подчеркивания (на самом деле в python3 вы также можете использовать символы юникода, и это становится сложнее проверить, но возможно).
    7. Код не обрабатывает исходный код, который заканчивается строкой цикла с отступом. например for x in a: indented_last_line_of_code() выход print не будет добавлен (легко исправить, добавив проверку на in_loop вне for функции, чтобы увидеть, есть ли у нас такая ситуация).

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

    11.06.2013
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..