Построение оператора if из данных клиента в python - PullRequest
0 голосов
/ 13 апреля 2010

Мне нужно построить оператор if из данных, поступающих от клиента, как показано ниже:

условия: условие1, условие2, условие3, условие4 логические операторы: lo1, lo2, lo3 (возможные значения: "и" "или")

Например.

if condition1 lo1 condition2 lo3 condition4:
    # Do something

Я могу думать о eval / exec, но не уверен, насколько они безопасны! Есть ли лучший подход или альтернатива? Ценю ваши ответы:)

PS: на стороне клиента: Flex, на стороне сервера: Python, через Интернет

Спасибо

Ответы [ 3 ]

1 голос
/ 15 апреля 2010

Не используйте eval. Это огромный риск для безопасности. Если ваши условия относительно просты, я бы посоветовал предоставить пользователю приличный гибкий графический интерфейс для их ввода, не просто текстовую область, а настоящий инструмент для создания выражений. Посмотрите на функции «расширенного поиска» в любом достаточно сложном поисковом приложении для примеров. Затем возьмите данные, которые они ввели в виджеты GUI, и представьте их как объекты. Вы бы смоделировали свое выражение как цепочку выражений (15 «утка» 5.3 и т. Д.), Операторов (<> =! = И т. Д.) И конъюнкций (И ИЛИ НЕ и т. Д.) Или что-то в этом духе. Затем я собрал бы их в JSON, разархивировал их в объекты Python в коде Python на стороне сервера и оценил их с помощью специального кода Python.

Теперь, если набор операторов и выражений очень велик, рассмотрите возможность определения Domain Specific Language и его синтаксического анализа, что будет намного безопаснее, чем оценка необработанного кода. Я не делал DSL самостоятельно, но мне сказали, что у python есть хорошие библиотеки для этого ( PLY может помочь).

1 голос
/ 15 апреля 2010

Определите вашу собственную функцию, которая принимает два условия и оператор и оценивает:

def my_eval(condition1, lo, condition2)
    return {
      'and': condition1 and condition2,
      'or': condition1 or condition2
           }[lo]

и затем оцените лот:

condition = conditions[0]
for cond, op in zip(conditions[1:], operators):
    condition = my_eval(condition, op, cond)

Не стесняйтесь предварительно обрабатывать condition1 и condition2 в my_eval, вы, вероятно, не намерены проверять строки на правду: -)

0 голосов
/ 13 апреля 2010

Ответ Игнасио - путь. Просматривайте свои данные, полностью выстраивая свое сложное состояние. Но вам придется использовать eval для базовых условий:

condition = eval(conditions[0])
for cond, op in zip(conditions[1:], operators):
    lop = operator.and_ if op == "and" else operator.or_
    condition = lop(condition, eval(cond))

if condition:
    # Do something

Возможно, вы захотите убедиться, что в вашем списке условий нет «злых» условий, например гарантируя, что они всегда содержат оператор сравнения (==, <=, ....). </p>

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