Python: передать неравенство как строку в dict для оценки - PullRequest
3 голосов
/ 02 августа 2011

Мне нужно передать неравенства в функцию для оценки внутри функции. Есть ли способ оценки неравенства, если передается в виде строки? Или я должен передать представление неравенства и использовать операторы if / else для генерации знака?

Ответы [ 2 ]

4 голосов
/ 02 августа 2011

Вы можете использовать модуль operator и передать ему соответствующий метод:

import operator

def check(op, a, b)
    return op(a,b)

op = operator.ne
check(op, 2,3)


>>> True
3 голосов
/ 02 августа 2011

Ваш вопрос немного расплывчат, но звучит так, будто вы хотите оценить строку, содержащую выражение (например, x > 5). Вместо того, чтобы делать это, что является излишне сложным и потенциально опасным, просто определите функцию обычным способом или с использованием лямбда-выражения.

def gt5(x):
    return x > 5

или

gt5 = lambda x: x > 5

Они оба эквивалентны; теперь вы можете обойти gt5 так, как вам нравится, и когда придет время, вы просто позвоните ему

y = 6
if gt5(y):
    ...

Как показывает ответ Геррата , модуль оператора *1014* также может быть полезен для подобных вещей.


Теперь, когда я знаю, что вы обрабатываете пользовательские строки, я бы определенно предложил создать словарь, который отображает строки в функции. (Возможно, это то, что вы имели в виду в своем заголовке?) Передача пользовательских строк в getattr кажется плохой в нескольких отношениях. Что произойдет, если вы захотите добавить строку, которая не соответствует атрибуту operator? Что произойдет, если пользователь передаст строку, соответствующую закрытому атрибуту? Лучше создать собственный словарь, отображающий строки в функции. Диктовка позволяет вам указать только те строки, которые вы хотите принять.

func_dict = {
    'lt'   : operator.lt,
    'gt'   : operator.gt,
    'nand' : lambda x, y: not (x and y)
}

Вы все еще можете сохранить свою работу, используя getattr + operator, чтобы построить диктат из списка строк, которые вы хотите принять. Что-то вроде:

func_dict = dict((s, getattr(operator, s)) for s in ['lt', 'gt'])

Затем обновите func_dict примерно так:

custom_dict = {
    'nand' : lambda x, y: not (x and y)
}

func_dict.update(custom_dict)

Оттуда вы можете легко вызывать функции в dict следующим образом:

>>> func_dict['lt'](5, 7)
True
...