python convert a string to an operator

2020-04-16 04:33发布

问题:

Is it possible to convert a string to an operator in python? I would like to pass a condition to a function

Ideally it would look like this:

def foo(self, attribute, operator_string, right_value):
    left_value = getattr(self, attribute)
    if left_value get_operator(operator_string) right_value:
         return True
    else:
         return False

bar.x = 10
bar.foo('x', '>', 10)
[out] False
bar.foo('x', '>=', 10)
[out] True

I could make a dictionary where keys are strings and values are functions of the operator module. I would have to change foo definition slightly:

operator_dict = {'>', operator.lt,
                 '>=', operator.le}
def foo(self, attribute, operator_string, right_value):
    left_value = getattr(self, attribute)
    operator_func = operator_dict[operator_string]
    if operator_func(left_value, right_value):
         return True
    else:
         return False

This means I have to make this dictionary, but is it really necessary?

回答1:

You can use eval to dynamically build a piece of Python code and execute it, but apart from that there are no real alternatives. The dictionary-based solution is much more elegant and safe, however.

Apart from that, is it really that bad? Why not shorten it a bit …

return operator_dict[operator_string](left_value, right_value)


回答2:

The way the problem is specified I don't see why you can't pass operator.le to the function instead of ">=".

If this operator_string coming from a database or file or something or are you passing it around in your code?

bar.foo('x', operator.le , 10)

Are you just looking to have a convenient shorthand? Then you might do something like:

from operator import le
bar.foo('x', le, 10)

If the real problem here is that you have code or business rules coming in from a database or datafile then maybe you actually need to look at writing a little parser that will map your input into these objects and then you could take a look at using a library like pyparsing, ply, codetalker, etc.