Python: я должен использовать eval, exec или ..? - PullRequest
4 голосов
/ 16 февраля 2011

Я пытаюсь сделать следующее утверждение более гибким:

for posting in page.findAll(attrs = {"id": re.compile(r'''post\d+''')}):

Следующая часть динамически извлекается из файла CSV и сохраняется в строке (например, в строке с именем test).CSV хранится в безопасном месте, доступном только для администраторов.

attrs = {"id": re.compile(r'''post\d+''')}

Можно ли интегрировать переменную следующим образом, используя eval (test) или exec (test) вместо только test?

for posting in page.findAll(test)):

Ответы [ 4 ]

5 голосов
/ 16 февраля 2011

Если вы хотите запустить код из пользовательского ввода (содержимое файла вводится), вам понадобится eval или exec, по этим именам или каким-либо другим (в частности, вам нужно exec для операторов - назначение заявление).

Но вы не хотите (и не должны) этого делать, потому что это зло, небезопасно, совершенно ненужно и т. Д. Отбросьте назначение (просто сохраните dict) и вызов re.compile, затем вы можете использовать ast.literal_eval, и вы в полной безопасности (вам все равно нужно отлавливать синтаксические ошибки и все остальное, что может пойти не так, чтобы отобразить разумное сообщение об ошибке, но вредоносный код должен быть почти невозможным, и он не настолько грязный) Вы можете применить re.compile после загрузки, если вам это нужно.

1 голос
/ 16 февраля 2011

Наиболее безопасным является ast.literal_eval () :

>>> args = ast.literal_eval('{"a":1}')
>>> args
{'a': 1}

Вы можете использовать его как:

some_function_or_method(**args)
1 голос
/ 16 февраля 2011

Если вы не имеете абсолютно никакого контроля над источником CSV, избегайте любой ценой этих типов загрузки.

  • сохраняйте регулярное выражение как сериализованные данные, используя модуль pickle (или лучше простосохраните строку)
  • Сохраните ваши данные в формате JSON, используя модуль json
  • , запишите их в файл, используя модуль csv

Затем выполнитенапротив, получить данные из файла.

Если вы не можете управлять генерацией CSV, попробуйте извлечь данные вручную, используя split или модуль re.

evalи exec - «последний шанс».Избегайте их использования, если у вас нет других способов.

0 голосов
/ 16 февраля 2011

Ни то, ни другое - это Python - вы можете написать ряд именованных параметров и желаемых значений для вызова функции в качестве словаря.В этом случае словарь, значение которого для ключа "attrs" также является словарем.Просто добавьте "**" к имени словаря при вызове функции:

test= {"attrs": {\"id\": re.compile(r'''post\d+''')} }

for posting in page.findAll(**test}):
   (...)
...