Как найти переменную в коде

Альберт

@bigburn

Делаю неживое живым

Как найти необъявленные переменные в коде, не выполняя его?

есть файл х.py с кодом, например

a
b = 1
class C(D): pass
import e

Здесь мы можем видеть, что на переменные `a` и `D` программа будет ругаться (NameError, name ‘a’ not defined), т.к они не определены.

Как можно найти такие необъявленные переменные, не исполняя код?
Смотрю в сторону AST, возможно решение может быть где-то там.


  • Вопрос задан

    более трёх лет назад

  • 251 просмотр

Пригласить эксперта

Ответ на этот вопрос неоднозначен, потому что Python динамический язык. В общем случае код может производить практически любые действия от простого изменения globals() (например _ из стандартной gettext) до замены следующего кода на другой (например автоматический импорт модулей в библиотеке ipython-autoimport). Поэтому без выполнения кода не получится определить будет ли исключение NameError или нет.

Если вы не используете подобные идиомы в разработке, то помогут любые линтеры (например pyflakes, flake8, pylint), которые выведут отчёт по многим логическим/синтаксическим ошибкам в коде, включая неопределённые переменные. Если требуется программно определять, то возможно достаточно будет pyflakes.

Если для разработчика то берем PyCharm и в бой. Если автоматизация с проверкой кода то SonarQube, например


  • Показать ещё
    Загружается…

24 мая 2023, в 14:19

1000 руб./за проект

24 мая 2023, в 14:15

10000 руб./за проект

24 мая 2023, в 13:53

8500 руб./за проект

Минуточку внимания

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

Но если вам все же нужно разбивать этот файл как строку, то можно использовать “всемогущий” LINQ, ибо достаточно найти ключевые аспекты, по которым надо сделать поиск. У вас это строка, знак = и также знак ; (который должен быть в конце строки, но у вас почему-то его нет).

Имея это делаем примерно следующее:

var findValue = File.ReadAllLines("Test.txt")
    .FirstOrDefault(x => x.Contains("abc"))?
    .Split(new[] { '=', ';' }, StringSplitOptions.RemoveEmptyEntries)
    .LastOrDefault();

if (int.TryParse(findValue, out int result))
{
    Console.WriteLine(result);
}
  • File.ReadAllLines("Test.txt") – читаем файл как массив строк.
  • .FirstOrDefault(x => x.Contains("abc")) – из полученного файла берем ту строку, которая содержит abc. Тут есть пару но – если у вас надо найти определенный тип, то стоит дописать условие, если таких переменных много и они расположены в разных методах например, то тоже придется дописать! Данный вариант просто берет строку в надежде, что она у нас одна.
  • ? – Если предыдущий вызов не дал NULL, то мы выполняем код дальше, иначе пропускаем и выдаем NULL в результат.
  • .Split(new[] { '=', ';' }, StringSplitOptions.RemoveEmptyEntries) – разбиваем полученную строку по = и ; – это даст нам строковой массив, где первым значением будет все до =, вторым все после (но до ;), а 3-м все после ;. Так, как после ; обычно у нас пустота (я надеюсь, что она у вас там), то мы убираем эту пустоту при помощи StringSplitOptions.RemoveEmptyEntries.
  • .LastOrDefault(); – берем из полученного массива последнее значение. Если у вас после ; есть что-то еще, то тут строит наверно брать 2-е значение (то, что строго после =).

В findValue у нас будет string значение с необходимым числом, либо NULL, если такого нет. Остается нам это число преобразовать в правильный формат, int и делает это

int.TryParse(findValue, out int result)

Он вернет нам bool значение, где true – удалось преобразовать, а false – нет. Само значение он отдаст через out.

@mrb3k
Как сказали выше – Xpath или регулярки. Самый простой способ – Xpath.

Пример. Есть переменная [[MAIL_BODY]] с текстом:

<div style="font-family:Open Sans, Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:20px;text-align:left;color:#4F4F4F;"><div class="wrap" style="color: #333;"><div class="title" style="margin-bottom: 24px; line-height: 30px; font-size: 30px; font-weight: 700;">Используйте этот код для входа</div><div class="dear" style="margin-bottom: 12px;">Здравствуйте!</div><div class="content" style="margin-bottom: 12px;">Используйте этот код для подтверждения почты:</div><div class="code" style="margin-bottom: 12px; font-size: 20px; font-weight: 700; color: #FF4747;">6402</div><div class="tips">Вы сможете изменить пароль, почту и телефон в настройках профиля.</div><div class="tips" style="margin-bottom: 12px;">Если вы не запрашивали код подтверждения, проигнорируйте это письмо. Чтобы защитить аккаунт, измените пароль.</div><div class="kind">Хороших покупок,</div><div class="AliExpress"> AliExpress </div></div></div>

Чтобы получить из нее код (“6402”), используем действие “Xpath получить текст” и вводим корректный запрос Xpath (в данном случае //div[@class=”code”]. Всё.
453242d3-12f9-4457-bf26-cd8bddae3575-изображение.png

В редких случаях еще с помощью методов js можно ответ подправить.
Если бы полный текст HTML показал, написал бы Xpath по нему.

Добавить комментарий