f



Override 'and' and 'or'

Is it possible to override 'and' and/or 'or'? I cannot find a special
method for it... __and__ and __rand__ and __or__ and __ror__ are for
binary manipulation... any proposals?

Have marvelous sunday,
Marco

0
10/7/2007 1:52:15 PM
comp.lang.python 77058 articles. 5 followers. Post Follow

13 Replies
1415 Views

Similar Articles

[PageSpeed] 22

Dekker <m.aschwanden@gmail.com> wrote:
> Is it possible to override 'and' and/or 'or'? I cannot find a special
> method for it... __and__ and __rand__ and __or__ and __ror__ are for
> binary manipulation... any proposals?

If you want to customize the truth value testing you have to implement
__nonzero__

"
 __nonzero__(   self)
    Called to implement truth value testing, and the built-in operation
bool(); should return False or True, or their integer equivalents 0 or
1. When this method is not defined, __len__() is called, if it is
defined (see below). If a class defines neither __len__() nor
__nonzero__(), all its instances are considered true.
"

Keep in mind the relation between __len__ and __nonzero__

ps. why you need to customize such a thing?

-- 
Lawrence, oluyede.org - neropercaso.it
"It is difficult to get a man to understand 
something when his salary depends on not
understanding it" - Upton Sinclair
0
raims (182)
10/7/2007 2:17:33 PM
On Sun, 07 Oct 2007 13:52:15 +0000, Dekker wrote:

> Is it possible to override 'and' and/or 'or'?

Not without hacking the Python source code, in which case what you've got 
is no longer Python.

Why do you want to do so?


-- 
Steven.
0
steve9679 (1985)
10/7/2007 2:19:00 PM
Dekker a �crit :
> Is it possible to override 'and' and/or 'or'? I cannot find a special
> method for it... __and__ and __rand__ and __or__ and __ror__ are for
> binary manipulation... any proposals?

http://docs.python.org/ref/customization.html
"""
__nonzero__(  	self)
     Called to implement truth value testing, and the built-in operation 
bool(); should return False or True, or their integer equivalents 0 or 
1. When this method is not defined, __len__() is called, if it is 
defined (see below). If a class defines neither __len__() nor 
__nonzero__(), all its instances are considered true.
"""

Not that in Python, 'and' don't yield bools:

 >>> "aa" and "bb"
'bb'
 >>> "aa" and None # yields None
 >>> "aa" and 0
0
 >>> "aa" or "bb"
'aa'
 >>> 0 or "bb"
'bb'
 >>> None or "bb"
'bb'
 >>> "aa" or 0
'aa'
 >>> "aa" or None
'aa'
 >>>

HTH
0
10/7/2007 2:19:17 PM
Dekker wrote:
> Is it possible to override 'and' and/or 'or'? I cannot find a special
> method for it... __and__ and __rand__ and __or__ and __ror__ are for
> binary manipulation... any proposals?
> 
> Have marvelous sunday,
> Marco
> 
I guess you're looking for __nonzero__() 
<URL:http://docs.python.org/ref/customization.html>.

You don't actually override the boolean operators, you just tell the 
object how to tell others if it evaluates to True or False 
(Truth-testing isn't a binary operation; cf. bool(my_object)).

/W
0
lasses_weil (126)
10/7/2007 2:21:54 PM
Wildemar Wildenburger wrote:
> [whate everyone else wrote :(]
> 
> /W

Dangit! 4th of 4.
Gotta type quicker.

/W
0
lasses_weil (126)
10/7/2007 2:24:35 PM
On Sun, 07 Oct 2007 16:24:35 +0200, Wildemar Wildenburger wrote:

> Wildemar Wildenburger wrote:
>> [whate everyone else wrote :(]
>> 
>> /W
> 
> Dangit! 4th of 4.
> Gotta type quicker.


That's okay, in two weeks time there will be 139 messages in this thread, 
it will have devolved into an argument about whether Python's truth-
testing semantics are better or worse than whatever Java/Lisp/Haskell/
Ruby does, and *then* somebody will respond to the Original Poster with 
"customize the __and__ and __or__ methods of your class".

Happens every time.



-- 
Steven.
0
steve9679 (1985)
10/7/2007 2:47:57 PM
On 7 Okt., 16:19, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.au> wrote:
> On Sun, 07 Oct 2007 13:52:15 +0000, Dekker wrote:
> > Is it possible to override 'and' and/or 'or'?
>
> Not without hacking the Python source code, in which case what you've got
> is no longer Python.
>
> Why do you want to do so?
>
> --
> Steven.

Well I think it is not possible what I wanted to achieve. By
overriding the "and" and "or" keyword I wanted to return a new object:

SqlValueInt(4) and SqlValueInt(5) --> SqlOpAnd(SqlValueInt(4),
SqlValueInt(5))

This is only possible for: +, -, /, *, >, >=, ...

Well... I have to live with the (binary) __and__, __or__ option and
the user has to write:

SqlValueInt(4) & SqlValueInt(5) --> SqlOpAnd(SqlValueInt(4),
SqlValueInt(5))

Thanks for your input, but __nonzero__ is not of any help in this
case... I want to abuse the "magic" functions for some transformations
and not some evaluation.

Marco

0
10/7/2007 2:48:43 PM
Dekker wrote:
> Well... I have to live with the (binary) __and__, __or__ option and
> the user has to write:
> 
> SqlValueInt(4) & SqlValueInt(5) --> SqlOpAnd(SqlValueInt(4),
> SqlValueInt(5))
> 
> Thanks for your input, but __nonzero__ is not of any help in this
> case... I want to abuse the "magic" functions for some transformations
> and not some evaluation.
> 
Then again, you could always write a function that does this. I know, I 
know ...

/W
0
lasses_weil (126)
10/7/2007 3:26:03 PM
On Oct 7, 4:48 pm, Dekker <m.aschwan...@gmail.com> wrote:
> On 7 Okt., 16:19, Steven D'Aprano <st...@REMOVE-THIS-
>
> cybersource.com.au> wrote:
> > On Sun, 07 Oct 2007 13:52:15 +0000, Dekker wrote:
> > > Is it possible to override 'and' and/or 'or'?
>
> > Not without hacking the Python source code, in which case what you've got
> > is no longer Python.
>
> > Why do you want to do so?
>
> > --
> > Steven.
>
> Well I think it is not possible what I wanted to achieve. By
> overriding the "and" and "or" keyword I wanted to return a new object:
>
> SqlValueInt(4) and SqlValueInt(5) --> SqlOpAnd(SqlValueInt(4),
> SqlValueInt(5))
>
> This is only possible for: +, -, /, *, >, >=, ...
>
> Well... I have to live with the (binary) __and__, __or__ option and
> the user has to write:
>
> SqlValueInt(4) & SqlValueInt(5) --> SqlOpAnd(SqlValueInt(4),
> SqlValueInt(5))
>
> Thanks for your input, but __nonzero__ is not of any help in this
> case... I want to abuse the "magic" functions for some transformations
> and not some evaluation.
>
> Marco

You can see what "and" and "or" are actually doing:

import dis
dis.dis(lambda: x or y and z)

  1           0 LOAD_GLOBAL              0 (x)
              3 JUMP_IF_TRUE            11 (to 17)
              6 POP_TOP
              7 LOAD_GLOBAL              1 (y)
             10 JUMP_IF_FALSE            4 (to 17)
             13 POP_TOP
             14 LOAD_GLOBAL              2 (z)
        >>   17 RETURN_VALUE

Here you can see nicely that they are not implemented as specialized
opcodes but being compiled to jumps. This causes their lazy nature. If
"and" would be implemented as a normal ( eager ) operator a statement
like:

if l and l[0] == 2:
    BLOCK

would raise an IndexError if l is empty.



0
kay.schluehr (709)
10/7/2007 3:46:08 PM
Steven D'Aprano a écrit :
> On Sun, 07 Oct 2007 16:24:35 +0200, Wildemar Wildenburger wrote:
> 
>> Wildemar Wildenburger wrote:
>>> [whate everyone else wrote :(]
>>>
>>> /W
>> Dangit! 4th of 4.
>> Gotta type quicker.
> 
> 
> That's okay, in two weeks time there will be 139 messages in this thread, 
> it will have devolved into an argument about whether Python's truth-
> testing semantics are better or worse than whatever Java/Lisp/Haskell/
> Ruby does, and *then* somebody will respond to the Original Poster with 
> "customize the __and__ and __or__ methods of your class".

keyboard !-)
0
10/7/2007 3:48:53 PM
Kay Schluehr schrieb:
> On Oct 7, 4:48 pm, Dekker <m.aschwan...@gmail.com> wrote:
>> On 7 Okt., 16:19, Steven D'Aprano <st...@REMOVE-THIS-
>>
>> cybersource.com.au> wrote:
>>> On Sun, 07 Oct 2007 13:52:15 +0000, Dekker wrote:
>>>> Is it possible to override 'and' and/or 'or'?
>>> Not without hacking the Python source code, in which case what you've got
>>> is no longer Python.
>>> Why do you want to do so?
>>> --
>>> Steven.
>> Well I think it is not possible what I wanted to achieve. By
>> overriding the "and" and "or" keyword I wanted to return a new object:
>>
>> SqlValueInt(4) and SqlValueInt(5) --> SqlOpAnd(SqlValueInt(4),
>> SqlValueInt(5))
>>
>> This is only possible for: +, -, /, *, >, >=, ...
>>
>> Well... I have to live with the (binary) __and__, __or__ option and
>> the user has to write:
>>
>> SqlValueInt(4) & SqlValueInt(5) --> SqlOpAnd(SqlValueInt(4),
>> SqlValueInt(5))
>>
>> Thanks for your input, but __nonzero__ is not of any help in this
>> case... I want to abuse the "magic" functions for some transformations
>> and not some evaluation.
>>
>> Marco
> 
> You can see what "and" and "or" are actually doing:
> 
> import dis
> dis.dis(lambda: x or y and z)
> 
>   1           0 LOAD_GLOBAL              0 (x)
>               3 JUMP_IF_TRUE            11 (to 17)
>               6 POP_TOP
>               7 LOAD_GLOBAL              1 (y)
>              10 JUMP_IF_FALSE            4 (to 17)
>              13 POP_TOP
>              14 LOAD_GLOBAL              2 (z)
>         >>   17 RETURN_VALUE
> 
> Here you can see nicely that they are not implemented as specialized
> opcodes but being compiled to jumps. This causes their lazy nature. If

Very cool, didn't know that.

Diez
0
deets (3351)
10/7/2007 3:57:31 PM
On 8/10/2007 1:57 AM, Diez B. Roggisch wrote:
> Kay Schluehr schrieb:

>> You can see what "and" and "or" are actually doing:
>>
>> import dis
>> dis.dis(lambda: x or y and z)
>>
>>   1           0 LOAD_GLOBAL              0 (x)
>>               3 JUMP_IF_TRUE            11 (to 17)
>>               6 POP_TOP
>>               7 LOAD_GLOBAL              1 (y)
>>              10 JUMP_IF_FALSE            4 (to 17)
>>              13 POP_TOP
>>              14 LOAD_GLOBAL              2 (z)
>>         >>   17 RETURN_VALUE
>>
>> Here you can see nicely that they are not implemented as specialized
>> opcodes but being compiled to jumps. This causes their lazy nature. If
> 
> Very cool, didn't know that.
> 

<rant>

Not very cool at all IMHO, because:
1. There's no other way to avoid unnecessarily evaluating the second 
operand besides using jumps.
2. POP_TOP [used even in normal test & jump situations] is horrible, and 
there are long-known better ways of doing it:

E.g. "Recursive Descent Compiling", by A.J.T. Davie and R. Morrison 
[pub: Ellis Horwood, Chichester, 1981] says on page 146: "... jumptt 
branches if the top stack element is true and merely removes it 
otherwise. A similar sequence can be used for 'and' but with jumpff 
replacing jumptt."

C Python uses two JUMP_IF_bool[_NEVER_POP] instructions, followed in 
most cases by POP_TOP.

E.g.
 >>> dis.dis(lambda: tval if arg else fval)
   1           0 LOAD_GLOBAL              0 (arg)
               3 JUMP_IF_FALSE            7 (to 13)
               6 POP_TOP
               7 LOAD_GLOBAL              1 (tval)
              10 JUMP_FORWARD             4 (to 17)
         >>   13 POP_TOP
              14 LOAD_GLOBAL              2 (fval)
         >>   17 RETURN_VALUE
 >>>

IMHO 4 more jump instructions
     2 x JUMP_IF_bool_ALWAYS_POP (simple cases)
and 2 x JUMP_IF_bool_ELSE_POP (and/or)
would be very useful.

</rant>
0
sjmachin (3097)
10/7/2007 9:21:50 PM
On 10/7/07, Dekker <m.aschwanden@gmail.com> wrote:
>
> Well I think it is not possible what I wanted to achieve. By
> overriding the "and" and "or" keyword I wanted to return a new object:
>
> SqlValueInt(4) and SqlValueInt(5) --> SqlOpAnd(SqlValueInt(4),
> SqlValueInt(5))

PEP 335 is a proposal to allow overriding of the logical 'and', 'or' operators:

See <http://www.python.org/dev/peps/pep-0335/> and the discussion of
it at <http://mail.python.org/pipermail/python-dev/2004-September/048791.html>

A.
0
adurdin (93)
10/8/2007 2:55:01 PM
Reply: