Передача выражений в функции?
Я не совсем уверен, что я имею в виду, поэтому, пожалуйста, потерпите меня
В 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
Короткий ответ: вы не можете. Результат оценки выражения передается функции, а не самому выражению.