Forgetting "()" when calling methods

Andrew Bennetts andrew-pythonlist at puzzling.org
Sun Apr 27 04:30:31 EDT 2003


On Sun, Apr 27, 2003 at 07:52:37AM +0000, Alex Martelli wrote:
> Andrew Bennetts wrote:
>    ...
> > lack of a better word.  It's usually not any clearer to say
> >     
> >     if len(myList) == 0:
> >         print "I have a list of stuff"
> 
> The "== 0" part here is making it to the reverse of what you probably mean.

Oops, yes.  Thanks.  Another reason not to spell it that way ;)

> > than
> > 
> >     if myList:
> >         print "I have a list of stuff"
> 
> Absolute agreement here.

It's good to know we have at least *some* common ground :)

> > I think the same applies to testing to see if a variable holds a callable,
> 
> Not at all.  "if callable(thevariable):" is the one obvious way to check
> THAT.  "if thevariable:" is going to have you try to call the number 23,
> the string 'loolapalooza', and non-empty dicts and lists.

I disagree.  Attempting to call any of those things will fail immediately,
and with an obvious error message.  I see no need for LBYL here.

> > just as much as it applies to checking the length of something.  Removing
> 
> The two cases are very different.  "if len(myList):" is equivalent to
> "if myList:" *for a known given type of myList* -- a container.  In
> the callable case, you _don't know_ the type -- and are checking the
> VALUE to try and infer the TYPE.  Checking callable(f) is more obvious
> and direct -- it clearly and unambiguously shows what you're checking.

I don't think they're different at all.  If 

    if x:
         val = x[0]

is ok, why not

    if x:
         val = x()

as well?  If x isn't a container, and it is expected to be, then x[0] will
break -- and it can also break in the case where x is a dict, and len(x)
wouldn't necessarily help there.

Similarly, callable(x) doesn't guarantee that you can successfully call x
with some arbitrary arguments.  The only way is to try.  I don't see any
difference here at all.

In my opinion, "callable(f)" also clearly and unambiguously clutters the
code.  Maybe I'm overly sensitive, but I find "if func:" much more pleasant
to the eyes and faster to read than "if callable(func):".  The extra
punctuation and syllables get in the way of the meaning.

In both English and programming, I prefer to use the simplest, most direct
way of expressing something that I can.  I'm sure that most of the time I
could do better, but I try, and I think both my prose and my code is better
for it.  Requiring "if callable(func):" rather than "if func:" goes against
this instinct, with the only justification being to prevent an error that
has struck me only very rarely, and never proved confusing or difficult to
debug.  I don't like the tradeoff.

> > this feature will lead to unnecessarily longer code for minimal benefit.
> 
> I dispute the "unnecessarily" and the "minimal".  Tests for "is None"
> add clarity (when they're applicable), and tests for callable(f) even
> more so.  And giving newbies a little help by diagnosing a very common
> newbie error more promptly would help (or at least it might, were it
> not for some newbies' insistence that the diagnosis should be performed
> by static analysis instead -- it just can't, and thus said insistence
> convinces me that this is not worth putting to a PEP -- however, I find
> the arguments against it quite unconvincing, except for the "we can't
> break this idiom because even though it's inferior it's widely used").

Personally, most of the time I use "if x:" rather than "if x is not None:",
even if I know the only expected false value will be None.  Why?  Because,
to me, adding the three extra words slows down comprehension -- particularly
the "not" -- and obscures the essence of what I'm trying to say.  So I
disagree that tests for "is not None" add clarity.  I reserve testing
against None to those times when I *really* need it, so that when I see it
in my code, I immediately recognise there probably an intentional
distinction between None, and 0 or '' or [].

I don't teach newbies, so I can't really comment on how much of an
impediment this is to them.  But recalling my own experiences, and the few
times I have helped newbies, I can't say that I remember it ever being an
issue.

So I disagree with you that "if x:" is necessarily inferior to "if
callable(x):" or "if x is not None:".

So I stick by my assesment: it is an unnecessary change will at best minimal
benefit.  I've never been seriously inconvenienced by callables having
__nonzero__.  I feel I would be inconvenienced regularly if they suddenly
became the only Python type that didn't.

-Andrew.






More information about the Python-list mailing list