Passing expressions to functions?

前端 未结 6 454

I\'m not quite sure what I mean here, so please bear with me..

In SQLAlchemy, it appears I\'m supposed to pass an expression to filter() in certain cases. When I try to

相关标签:
6条回答
  • 2021-02-01 20:19

    You have to implement __eq__() . For example ::

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

    Then, for the function, which you want to get the expression, like ::

    def my_func(expr):
        # deal with the expression
        print(expr)
    
    >>> a = A()
    >>> my_func(a == 1)
    (<__main__.A object at 0x1015eb978>, '==', 1)
    
    0 讨论(0)
  • 2021-02-01 20:23

    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.

    0 讨论(0)
  • 2021-02-01 20:26

    It appears you can return tuples from 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)
    
    0 讨论(0)
  • 2021-02-01 20:29

    Short answer: You can't. The result of the expression evaluation is passed to the function rather than the expression itself.

    0 讨论(0)
  • 2021-02-01 20:32

    You can't. The expression 5 == 5 is evaluated and only then is the result passed to someFunc. The function just gets True (the True object, to be precise), no matter what the expression was.

    Edit: Concerning your edit, this question is kind of close.

    Edit 2: You could just pass the expression as a string and use eval, like this:

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

    Don't know whether that helps you. Keep in mind that eval is a powerful tool, so it's dangerous to pass arbitrary (and possibly even user-generated) input to it.

    0 讨论(0)
  • 2021-02-01 20:33

    An even more pythonic variant of Nelson's solution is to use the operator functions from the operator module in the standard library; there is no need to create your own lambdas.

    >>> from operator import eq
    >>> def magic(left, op, right):
    ...   return op(left, right)
    ... 
    >>> magic(5, eq, 5)
    True
    
    0 讨论(0)
提交回复
热议问题