Changing self: if self is a tree how to set to a different self

Bart Kastermans kasterma at bart-kastermanss-macbook.local
Sun Jul 13 07:19:48 EDT 2008


Paul McGuire <ptmcg at austin.rr.com> writes:

> On Jul 12, 6:18 am, Bart Kastermans <kaste... at bart-kastermanss-
> macbook.local> wrote:
>> This uses the function:
>>
>> def NoneOr (tree, mem_function, *arguments):
>>     """ if tree is not None then tree.mem_function (arguments). """
>>     if tree == None:
>>         return None
>>     else:
>>         return getattr (tree, mem_function) (*arguments)
>>
>> Bart
>
> <persnickety>

First I want to say these comments are absolutely great.  I *very*
much appreciated getting them.  This kind of analysis and thinking
about code is exactly what I want to learn for myself; so this helped
me a lot.  From the many interesting thoughts I got from this there is
only one that is a bit dissonant with me; it is the next paragraph.

> This code reads wrongly to me on a couple of levels.  First, I think
> the general computing consensus is that if-then-else is more readable/
> logical if you assert the positive condition for the then-part, and
> put the alternative condition in the else-part.  My impression is that
> the non-None-ness of tree is actually the positive assertion, as in:

I had been experimenting with exactly this in some of my code.  The
choice seemed to be between (in the cases I had in front of me):

1) filter out the bad cases and deal with them, then have the code do
the usual stuff,

2) set the conditions for being the usual case, then later deal with
the bad stuff.

I had been converging towards (1) as in

def func (inputs):
    if inputs bad one way:
        deal with it

    if inputs bad another way:
        deal with it too

    take care of the generic remaining case

case (2) would result in something like:

def func (inputs):
    if inputs are not bad in any way:
       take care of the generic case
    elif in puts bad in one way:
       deal with it
    else:  # bad in another way
       deal with it too

Did I represent the case distinction as you had it in mind?  I'll keep
this more in mind when writing stuff and see how it works out.

<persnickety>
Better keep with "more readable", logically these are clearly
equivalent.
</persnickety>

>
>     if tree != None:
>         return getattr(tree, mem_function)(*arguments)
>     else:
>         return None
>
> Next, the more Pythonic test for None-ness is most clearly written as:
>
>     if tree is not None:
>
> as there is only one None, and the identity "is not" check is simpler/
> faster for Python to execute (and possibly - and more importantly -
> also simpler for readers to follow, as this reads more like a
> continuous sentence instead of a mixture of prose and mathematical
> notations).
>
> One might even suggest you could further abbreviate this test to:
>
>     if tree:
>
> and get the same behavior.  I would quibble with that, however, that
> this merely exploits a side-effect of Python, in which None values are
> always False, and *most* non-None values are True.  But Python also
> interprets many non-None values as False, such as 0, or empty
> containers, such as lists, tuples, dicts, and strings.  In fact, your
> tree class sounds like a structured container to me, and it would be
> reasonable to assume that you might implement __nonzero__ (pre-Python
> 2.6) or __bool__ (Python 2.6 and later) in your class to return False
> for an empty tree, which would still be a valid and not-None tree.
> You should be able to invoke methods on an empty tree just as one can
> call "".upper().  So for this case, I would stick with the more
> explicit "if tree is not None".
>
> Another Pythonicity is that methods will *always* return a value, even
> if you do not write a return statement - and that value is None.  So
> if you assert the tree-not-None as the if condition, you don't even
> need the else part.  You could just write:
>
>     def NoneOr (tree, mem_function, *arguments):
>         """ if tree is not None then tree.mem_function (arguments).
> """
>         if tree is not None:
>             return getattr(tree, mem_function)(*arguments)
>
> Surprisingly, this actually reads almost verbatim from your doc
> string!  So I would guess that this implementation is probably closest
> to your original intent for this method.  Still, for explicitness'-
> sake, you might want to keep the else-part, just to make your intent
> clear and spelled-out.  (Complaining about the presence or absence of
> this bit of code goes beyond "persnickety"...)
> </persnickety>
>
> Note that the original code is perfectly valid Python, and will run
> just as efficiently as any of my alternative suggestions, which is why
> I enclosed my comments in 'persnickety' (http://
> dictionary.reference.com/browse/persnickety) tags.
>
> -- Paul



More information about the Python-list mailing list