Dynamic comparison operators

M

mlangenhoven

I would like to pass something like this into a function
test(val1,val2,'>=')

and it should come back with True or False.

Is there a way to dynamically compare 2 values like this or will I have to code each operator individually?
 
A

Alain Ketterlin

I would like to pass something like this into a function
test(val1,val2,'>=')

and it should come back with True or False.

def test(x,y,c):
return c(x,y)

Call with: test(v1,v2, lambda x,y:x<=y ). A bit noisy imho.

If you have a finite number of comparison operators, put them in a dict:

compares = dict([ ("<",lambda x,y:x<y),
("|<",lambda x,y: x.startswith(y)),
... ])

and use them like: test(v1,v2,compares["<="]), or simply:
compares["<="](v1,v2)

-- Alain.
 
J

Jussi Piitulainen

Alain said:
def test(x,y,c):
return c(x,y)

Call with: test(v1,v2, lambda x,y:x<=y ). A bit noisy imho.

Re noisy:

import operator as o

test(v1, v2, o.le)
 
C

Colin J. Williams

I would like to pass something like this into a function
test(val1,val2,'>=')

and it should come back with True or False.

Is there a way to dynamically compare 2 values like this or will I have to code each operator individually?

Would something like the following meet your need?

Yes, it would be nice if there were a b.__name__ constant.

Colin W.
'''
I would like to pass something like this into a function
test(val1,val2,'>=')

and it should come back with True or False.

Is there a way to dynamically compare 2 values like this or will I have
to code each operator individually?
'''
def test(text):
return eval(text)

a= 25
b= 50

print test('a == b')
print test('a != b')
print test('a <= b')
 
S

Steven D'Aprano

Would something like the following meet your need?

Yes, it would be nice if there were a b.__name__ constant.

What is "a b.__name__ constant", and how will it be useful?

As for your solution using eval, please, please, PLEASE do not encourage
newbies to write slow, insecure, dangerous code. There are enough
security holes in software without you encouraging people to create more.

* eval is slow.

* eval is dangerous.

* eval is using a 200lb sledgehammer to crack a peanut.

Any time you find yourself thinking that you want to use eval to solve a
problem, take a long, cold shower until the urge goes away.

If you have to ask why eval is dangerous, then you don't know enough
about programming to use it safely. Scrub it out of your life until you
have learned about code injection attacks, data sanitation, trusted and
untrusted input. Then you can come back to eval and use it safely and
appropriately.

Today, your "test" function using eval is used only by yourself, at the
interactive interpreter. Tomorrow, it ends up in a web application, and
random hackers in China and script-kiddies in Bulgaria now have total
control of your server. Any time you hear about some piece of malware or
some virus infecting people's systems when they look at a PDF file,
chances are high that it is a code injection attack.

To learn more, you can start here:

http://cwe.mitre.org/top25/index.html

Two of the top three most common vulnerabilities are code injection
attacks, similar to the improper use of eval.

Here is the "eval injection" vulnerability:

http://cwe.mitre.org/data/definitions/95.html

Also google on "code injection" for many more examples.
 
P

Paul Rubin

I would like to pass something like this into a function
test(val1,val2,'>=')

and it should come back with True or False.

import operator

test(val1, val2, operator.ge)
 
J

Jon Clements

Any time you find yourself thinking that you want to use eval to solve a
problem, take a long, cold shower until the urge goes away.

If you have to ask why eval is dangerous, then you don't know enough
about programming to use it safely. Scrub it out of your life until you
have learned about code injection attacks, data sanitation, trusted and
untrusted input. Then you can come back to eval and use it safely and
appropriately.

I would +1 QOTW - but fear might have to cheat and say +1 to 2 paragraphs of the week :)

Jon.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,201
Latest member
KourtneyBe

Latest Threads

Top