Можно ли выполнить строки с отступом из другого файла в Python? - PullRequest
0 голосов
/ 27 сентября 2019

Скажите, у меня есть два файла demo.py

# demo.py
from pathlib import Path
for i in range(5):
    exec(Path('another_file.txt').read_text())

и another_file.txt (обратите внимание на отступ)

    print(i)

Можно ли запустить python demo.py?

NB. Это полезно при использовании Page (или wxformbuilder или дизайнера pyqt) для создания макета GUI, в котором автоматически создаются скелеты функций обратного вызова.Скелеты должны быть изменены, в то же время каждая итерация перезаписывает скелеты - фрагменты кода должны быть скопированы обратно.Во всяком случае, вы знаете, о чем я говорю, если вы использовали какой-либо из Page или wxformbuilder или конструктор pyqt.

1 Ответ

1 голос
/ 27 сентября 2019

Вы можете решить основную проблему, удалив отступ:

from pathlib import Path
import textwrap
for i in range(5):
    exec(textwrap.dedent(Path('another_file.txt').read_text()))

Есть еще две довольно серьезные проблемы с этим:

Здесь есть серьезные последствия для безопасности.Вы запускаете код, не включая его в свой проект.Мысль о том, что вы можете «беспокоиться о безопасности и о других проблемах позже», позже доставит вам боль.Вы увидите похожие советы на этом сайте, избегая SQL-инъекций.Эта более поздняя дата может никогда не наступить, и даже если это произойдет, есть очень реальный шанс, что вы не будете помнить или правильно определить все проблемы.Во-первых, лучше избегать проблем.

Кроме того, с таким динамическим кодом вы рискуете столкнуться с синтаксической ошибкой со стеком вызовов, который ничего не показывает о том, где находится код.из.Это не плохо для простых случаев, подобных этому, но по мере того, как вы добавляете все больше и больше сложности в проект, подобный этому, вы, скорее всего, обнаружите, что вы добавляете больше поддержки для устранения проблем, с которыми сталкиваетесь, вместо того, чтобы тратить свое время на добавление функций..

И объединение этих двух проблем может быть забавным.Это придумано, но если вы изменили цикл for на цикл while следующим образом:

i = 0
while i < 5:
    exec(textwrap.dedent(Path('another_file.txt').read_text()))
    i += 1

А затем изменили текстовый файл так:

    print(i)
    i += 1

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

Короче говоря, донне использовать eval.Будущее, за которое ты будешь благодарить за то, что облегчил себе жизнь.

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