Overriding logical operators?

A

Andrew Durdin

In Python, you can override the behaviour of most operators for a
class, by defining __add__, __gt__, and the other special object
methods.

I noticed that, although there are special methods for most operators,
they are conspicuously absent for the logical "or" and "and". I'm
guessing that the reason for this is that these operators
short-circuit if their first operand answers the whole question?

Would it be possible to allow overriding the logical operators, with
the caveat that overriding it would prevent short-circuiting?
 
M

Michael J. Fromberger

Andrew Durdin said:
In Python, you can override the behaviour of most operators for a
class, by defining __add__, __gt__, and the other special object
methods.

I noticed that, although there are special methods for most operators,
they are conspicuously absent for the logical "or" and "and". I'm
guessing that the reason for this is that these operators
short-circuit if their first operand answers the whole question?

Would it be possible to allow overriding the logical operators, with
the caveat that overriding it would prevent short-circuiting?

The implementation of "and" and "or" are special, as others have pointed
out. However, you do have some control over how they behave for objects
of user-defined classes. By overriding __nonzero_, you can define
whatever truth value you like for instances of a user-defined class.
See:

http://docs.python.org/lib/truth.html

This would not, in itself, "override" the behaviour of "and" and "or",
in the sense that you were describing, but it would let you control the
outcome for objects of your particular class.

-M
 
A

Andrew Durdin

The implementation of "and" and "or" are special, as others have pointed
out. However, you do have some control over how they behave for objects
of user-defined classes. By overriding __nonzero_, you can define
whatever truth value you like for instances of a user-defined class.

I suppose now I ought to say why I need to to do more than that. I've
got a situation where I want to construct an expression, but evaluate
it later when I get more information. I came up with a "DelayedEval"
class, the instances of which can have operations performed on them,
but the result is not evaluated until a particular method is called.
I'm currently overriding all the operators I can, so that these
instances can be handled in a fairly normal fashion for the most part.
For example:

foo = DelayedEval()
foo = (-foo + 15) * 3
foo_positive = (foo >= 0)

print foo.evaluate(10) # prints 15
print foo.evaluate(20) # prints -15
print foo_positive.evaluate(10) # prints True
print foo_positive.evaluate(20) # prints False

In this situation, merely overriding the __nonzero__ method will not
allow me to delay the evaluation of the logical boolean operators; to
do that I need to be able to override them.

The alternative solution that I can see to the issue is to use lambdas
to create the expressions I need, and calling them to evaluate them,
e.g.:

foo = lambda v: (-v + 15) * 3
foo_positive = lambda v: (foo(v) >= 0)

This will work, but having to manually chain the evaluation in this
way is a little awkward. It also doesn't allow me to print the
expressions. With the DelayedEval class, I can do this:

print foo_positive # prints (((-(value) + 15) * 3) >= 0)
 
M

Michael Hudson

Andrew Durdin said:
In Python, you can override the behaviour of most operators for a
class, by defining __add__, __gt__, and the other special object
methods.

I noticed that, although there are special methods for most operators,
they are conspicuously absent for the logical "or" and "and".

That's because they're not operators, they're flow control constructs.
Well, maybe that's not a helpful answer, but it's one you haven't had
yet :)
Would it be possible to allow overriding the logical operators, with
the caveat that overriding it would prevent short-circuiting?

I think this would be a foul abomination. But maybe that's just me.
(I don't really approve of operator overloading either).

Cheers,
mwh
 

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

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top