Overloading and? was <RE: Should I prefer an external database>

Andrew Dalke adalke at mindspring.com
Tue Apr 22 20:38:30 CEST 2003

Bjorn Pettersen:
> From: Ian Bicking [mailto:ianb at colorstudy.com]
[... + SQLObject example]

> for paper in Paper.select(AND(Paper.q.title == 'foo',
>                               Paper.q.author.startswith('Bob'))):

> Does anyone know the reason for not allowing an overload of the and
> operator?

The 'and' and 'or' operators work on the boolean-ness of the objects,
and apply short-circuit behaviour.  This is different than other binary
operators, which don't short-circuit.

For example, consider

counter = 0
class Funky:
  def __nonzero__(self):
    global counter
    print "Hello!"
    assert counter == 0
    counter = 1
    return 1

>>> counter = 0
>>> a = Funky() or Funky()
>>> a

Note that __nonzero__ was only called once, not twice.

There's no way to implement that behaviour in Python, so
it cannot be overridden.  Eg, suppose there is an "__and__".
You might think it could look like

  def __and__(self, other):
      if bool(self): return self
      if bool(other): return other
      return False

However, this doesn't work because of the short-circuiting

  print 1 and 1/0

prints '1', and never evalutes 1/0.

BTW, what I've done for other projects which build up a parse
tree then evalute it is to hijack the arithmetic operators.  I've
used '*' for and, '+', for or, and '-' for 'but not'.  In that case, the
above expression is

> for paper in Paper.select(Paper.q.title == 'foo' +
>                                  Paper.q.author.startswith('Bob')):

                    dalke at dalkescientific.com

More information about the Python-list mailing list