Home » Coding » Python » Override 'and' and 'or'
Override 'and' and 'or' [message #15678] Sun, 07 October 2007 09:52 Go to next message
Dekker  is currently offline Dekker
Messages: 2
Registered: October 2007
Junior Member
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
Re: Override 'and' and 'or' [message #15682 is a reply to message #15678 ] Sun, 07 October 2007 10:17 Go to previous messageGo to next message
raims  is currently offline raims
Messages: 30
Registered: July 2007
Member
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
Re: Override 'and' and 'or' [message #15684 is a reply to message #15678 ] Sun, 07 October 2007 10:19 Go to previous messageGo to next message
Bruno Desthuilliers  is currently offline Bruno Desthuilliers
Messages: 277
Registered: July 2007
Senior Member
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
Re: Override 'and' and 'or' [message #15687 is a reply to message #15678 ] Sun, 07 October 2007 10:19 Go to previous messageGo to next message
steve  is currently offline steve
Messages: 106
Registered: July 2007
Senior Member
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.
Re: Override 'and' and 'or' [message #15689 is a reply to message #15678 ] Sun, 07 October 2007 10:21 Go to previous messageGo to next message
Wildemar Wildenburger  is currently offline Wildemar Wildenburger
Messages: 73
Registered: August 2007
Member
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
Re: Override 'and' and 'or' [message #15693 is a reply to message #15689 ] Sun, 07 October 2007 10:24 Go to previous messageGo to next message
Wildemar Wildenburger  is currently offline Wildemar Wildenburger
Messages: 73
Registered: August 2007
Member
Wildemar Wildenburger wrote:
> [whate everyone else wrote :(]
>
> /W

Dangit! 4th of 4.
Gotta type quicker.

/W
Re: Override 'and' and 'or' [message #15697 is a reply to message #15678 ] Sun, 07 October 2007 10:47 Go to previous messageGo to next message
steve  is currently offline steve
Messages: 106
Registered: July 2007
Senior Member
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.
Re: Override 'and' and 'or' [message #15699 is a reply to message #15687 ] Sun, 07 October 2007 10:48 Go to previous messageGo to next message
Dekker  is currently offline Dekker
Messages: 2
Registered: October 2007
Junior Member
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
Re: Override 'and' and 'or' [message #15710 is a reply to message #15699 ] Sun, 07 October 2007 11:26 Go to previous messageGo to next message
Wildemar Wildenburger  is currently offline Wildemar Wildenburger
Messages: 73
Registered: August 2007
Member
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
Re: Override 'and' and 'or' [message #15713 is a reply to message #15699 ] Sun, 07 October 2007 11:46 Go to previous messageGo to next message
Kay Schluehr  is currently offline Kay Schluehr
Messages: 35
Registered: August 2007
Member
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.
Re: Override 'and' and 'or' [message #15715 is a reply to message #15697 ] Sun, 07 October 2007 11:48 Go to previous messageGo to next message
Bruno Desthuilliers  is currently offline Bruno Desthuilliers
Messages: 277
Registered: July 2007
Senior Member
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 !-)
Re: Override 'and' and 'or' [message #15725 is a reply to message #15713 ] Sun, 07 October 2007 11:57 Go to previous messageGo to next message
deets  is currently offline deets
Messages: 132
Registered: July 2007
Senior Member
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
Re: Override 'and' and 'or' [message #17437 is a reply to message #15725 ] Sun, 07 October 2007 17:21 Go to previous message
John Machin  is currently offline John Machin
Messages: 60
Registered: July 2007
Member
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>
Previous Topic:Mysql class works like php
Next Topic:finding out the call (and not only the caller)
Goto Forum:
  


Current Time: Fri May 16 02:39:04 EDT 2008

Total time taken to generate the page: 0.40123 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 2.7.7.
Copyright ©2001-2007 FUD Forum Bulletin Board Software