Home » Coding » Python » Override 'and' and 'or'
| Override 'and' and 'or' [message #15678] |
Sun, 07 October 2007 09:52  |
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 #15699 is a reply to message #15687 ] |
Sun, 07 October 2007 10:48   |
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 #15713 is a reply to message #15699 ] |
Sun, 07 October 2007 11:46   |
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 #15725 is a reply to message #15713 ] |
Sun, 07 October 2007 11:57   |
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  |
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>
|
|
|
Goto Forum:
Current Time: Fri May 16 02:39:04 EDT 2008
Total time taken to generate the page: 0.40123 seconds |