Override 'and' and 'or'

D

Dekker

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
 
L

Lawrence Oluyede

Dekker said:
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?
 
S

Steven D'Aprano

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?
 
B

Bruno Desthuilliers

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:

HTH
 
W

Wildemar Wildenburger

Dekker said:
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
 
S

Steven D'Aprano

Wildemar said:
[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.
 
D

Dekker

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?

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
 
W

Wildemar Wildenburger

Dekker said:
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
 
K

Kay Schluehr

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)
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.
 
B

Bruno Desthuilliers

Steven D'Aprano a écrit :
Wildemar said:
[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 !-)
 
D

Diez B. Roggisch

Kay said:
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)

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
 
J

John Machin

Kay Schluehr schrieb:

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. 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)
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>
 
A

Andrew Durdin

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top