Override 'and' and 'or'

Discussion in 'Python' started by Dekker, Oct 7, 2007.

  1. Dekker

    Dekker Guest

    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
    Dekker, Oct 7, 2007
    #1
    1. Advertising

  2. 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?


    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
    Lawrence Oluyede, Oct 7, 2007
    #2
    1. Advertising

  3. 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.
    Steven D'Aprano, Oct 7, 2007
    #3
  4. 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
    Bruno Desthuilliers, Oct 7, 2007
    #4
  5. 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
    Wildemar Wildenburger, Oct 7, 2007
    #5
  6. Wildemar Wildenburger wrote:
    > [whate everyone else wrote :(]
    >
    > /W


    Dangit! 4th of 4.
    Gotta type quicker.

    /W
    Wildemar Wildenburger, Oct 7, 2007
    #6
  7. 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.
    Steven D'Aprano, Oct 7, 2007
    #7
  8. Dekker

    Dekker Guest

    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
    Dekker, Oct 7, 2007
    #8
  9. 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
    Wildemar Wildenburger, Oct 7, 2007
    #9
  10. Dekker

    Kay Schluehr Guest

    On Oct 7, 4:48 pm, Dekker <> 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.
    Kay Schluehr, Oct 7, 2007
    #10
  11. 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 !-)
    Bruno Desthuilliers, Oct 7, 2007
    #11
  12. Kay Schluehr schrieb:
    > On Oct 7, 4:48 pm, Dekker <> 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
    Diez B. Roggisch, Oct 7, 2007
    #12
  13. Dekker

    John Machin Guest

    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>
    John Machin, Oct 7, 2007
    #13
  14. On 10/7/07, Dekker <> 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.
    Andrew Durdin, Oct 8, 2007
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kurt Milligan
    Replies:
    1
    Views:
    427
    Darryl L. Pierce
    Sep 15, 2003
  2. bigbinc

    Preprocessor gcc and override

    bigbinc, Jan 2, 2004, in forum: C++
    Replies:
    2
    Views:
    428
    Jacques Labuschagne
    Jan 2, 2004
  3. Jun Woong

    Re: Override malloc,calloc,realloc and free?

    Jun Woong, Jun 26, 2003, in forum: C Programming
    Replies:
    0
    Views:
    1,079
    Jun Woong
    Jun 26, 2003
  4. Dan Pop
    Replies:
    0
    Views:
    897
    Dan Pop
    Jun 26, 2003
  5. Stephan Kämper
    Replies:
    2
    Views:
    191
    Stephan Kämper
    Jan 24, 2005
Loading...

Share This Page