Передающие выражения к функциям?

Я не совсем уверен, что я имею в виду здесь, поэтому терпите меня..

В 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

Что относительно того, если один из параметров был объектом?

17
задан Georgy 9 July 2019 в 13:32
поделиться

6 ответов

You can achieve your example if you make "op" a function:

>>> 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

This is more Pythonic than passing a string. It's how functions like sort() work.

Those SQLAlchemy examples with filter() are puzzling. I don't know the internals about SQLAlchemy, but I'm guessing in an example like query.filter(User.name == 'ed') what's going on is that User.name is a SQLAlchemy-specific type, with an odd implementation of the __eq() function that generates SQL for the filter() function instead of doing a comparison. Ie: they've made special classes that let you type Python expressions that emit SQL code. It's an unusual technique, one I'd avoid unless building something that's bridging two languages like an ORM.

26
ответ дан 30 November 2019 в 11:52
поделиться

Вы не можете. Выражение 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 является мощным инструментом, поэтому передавать произвольный (и, возможно, даже пользовательский) ввод в него опасно.

1
ответ дан 30 November 2019 в 11:52
поделиться

Вы должны реализовать __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)
1
ответ дан 30 November 2019 в 11:52
поделиться

Похоже, вы можете возвращать кортежи из 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)
1
ответ дан 30 November 2019 в 11:52
поделиться

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

>>> from operator import eq
>>> def magic(left, op, right):
...   return op(left, right)
... 
>>> magic(5, eq, 5)
True
7
ответ дан 30 November 2019 в 11:52
поделиться

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

0
ответ дан 30 November 2019 в 11:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: