Store comparison in variable (or execute comparison when it's given as an string)
I'd like to know if the super-powerful python allows to store a comparison in a variable or, if not, if it's possible calling/executing a comparison when given as an string ("==" or "!=")
I want to allow the users of my program the chance of giving a comparison in an string.
For instance, let's say I have a list of... "products" and the user wants to select the products whose manufacturer is "foo". He could would input something like: Product.manufacturer == "foo" and if the user wants the products whose manufacturer is not "bar" he would input Product.manufacturer != "bar"
If the user inputs that line as an string, I create a tree with an structure like:
!=
/ \
manufacturer bar
I'd like to allow that comparison to run properly, but I don't know how to make it happen if != is an string.
The "manufacturer" field is a property, so I can properly get it from the Product class and store it (as a property) in the leaf, and well... "bar" is just an string. I'd like to know if I can something similar to what I do with "manufacturer": storing it with a 'callable" (kind of) thing: the property with the comparator: !=
I have tried with "eval" and it may work, but the comparisons are going to be actually used to query a MySQL database (using sqlalchemy) and I'm a bit concerned about the security of that...
Any idea will be deeply appreciated. Thank you!
PS: The idea of all this is being able to generate a sqlalchemy query, so if the user inputs the string: Product.manufacturer != "foo" || Product.manufacturer != "bar"
... my tree thing can generate the following: sqlalchemy.or_(Product.manufacturer !="foo", Product.manufacturer !="bar")
Since sqlalchemy.or_ is callable, I can 开发者_高级运维also store it in one of the leaves... I only see a problem with the "!="
I haven't used SQLAlchemy much, but I'd guess it uses Python's operator overloading to handle those comparisons. If that's true, then you can use the properties' magic methods. For example:
Product.manufacturer == 'bar' => Product.manufacturer.__eq__('bar')
Product.manufacturer != 'foo' => Product.manufacturer.__ne__('foo')
You should be able to do a getattr
on the property object for the appropriate magic method:
method_map = {'==': '__eq__', '!=': '__ne__'}
comparison = getattr(Product.manufacturer, method_map[op]) # Here, 'op' is the operator (!=)
sqlalchemy.or_(comparison('foo'), comparison('bar')) # Equivalent to: Product.manufacturer != 'foo' || Product.manufacturer != 'bar'
Hope this helps :)
精彩评论