Передача выражений в функции?

Я не совсем уверен, что я имею в виду, поэтому, пожалуйста, потерпите меня

В SQLAlchemy, кажется, я должен передать выражение в filter() в некоторых случаях. Когда я пытаюсь реализовать что-то подобное, я получаю:

>>> def someFunc(value):
...    print(value)

>>> someFunc(5 == 5)
True

Как получить значения, переданные в == внутри функции?

Я пытаюсь достичь чего-то вроде этого

 >>> def magic(left, op, right):
 ...    print(left+" "+op+" "+right)

 >>> magic(5 == 5)
 5 == 5

А что если один из параметров был объектом?

Ответ 1

Вы можете достичь своего примера, если сделаете "op" функцией:

>>> def magic(left, op, right):
...     return op(left, right)
...
>>> magic(5, (lambda a, b: a == b), 5)
True
>>> magic(5, (lambda a, b: a == b), 4)
False

Это больше Pythonic, чем передача строки. Это то, как работают функции вроде sort().

Эти примеры SQLAlchemy с filter() озадачивают. Я не знаю внутренностей о SQLAlchemy, но я предполагаю, что в примере, подобном query.filter(User.name == 'ed') происходит то, что User.name является специфичным для SQLAlchemy типом с нечетным реализация функции __eq() которая генерирует SQL для функции filter() вместо сравнения. То есть: они создали специальные классы, которые позволяют вам вводить выражения Python, которые испускают код SQL. Это необычная техника, которую я бы избегал, если бы не создавал что-то, связывающее два языка, например ORM.

Ответ 2

Еще более питонический вариант решения Nelson заключается в использовании операторских функций из модуля operator в стандартной библиотеке; нет необходимости создавать свои собственные лямбды.

>>> from operator import eq
>>> def magic(left, op, right):
...   return op(left, right)
... 
>>> magic(5, eq, 5)
True

Ответ 3

Вы не можете. Выражение 5 == 5 оценивается, и только тогда результат передается в someFunc. Функция просто получает True (объект True, если быть точным), независимо от того, что это выражение.

Изменить: Что касается вашего редактирования, этот вопрос близок.

Изменить 2: вы можете просто передать выражение в виде строки и использовать eval, например:

>>> def someFunc(expression_string):
...    print(expression_string, "evaluates to", eval(expression_string))

>>> someFunc("5 == 5")
5 == 5 evaluates to True

Не знаю, поможет ли это вам. Имейте в виду, что eval является мощным инструментом, поэтому ему опасно передавать произвольный (и, возможно, даже пользовательский) ввод.

Ответ 4

Кажется, вы можете возвращать кортежи из eq:

class Foo:
    def __init__(self, value):
            self.value = value

    def __eq__(self, other):
            return (self.value, other.value)


f1 = Foo(5)
f2 = Foo(10)
print(f1 == f2)

Ответ 5

Вам нужно реализовать __eq__(). Например:

class A(object):
    def __eq__(self, other):
        return (self, '==', other)

Затем для функции, которую вы хотите получить, например::

def my_func(expr):
    # deal with the expression
    print(expr)

>>> a = A()
>>> my_func(a == 1)
(<__main__.A object at 0x1015eb978>, '==', 1)

Ответ 6

Вам нужно обернуть все это как литеральную строку. Вы пытаетесь напечатать это как строку, которую я предполагаю, исправить?

Ответ 7

Короткий ответ: вы не можете. Результат оценки выражения передается функции, а не самому выражению.