How to make Python interpreter a little more strict?

BartC bc at freeuk.com
Sat Mar 26 20:36:12 EDT 2016


On 26/03/2016 23:30, John Pote wrote:

> So intrigued by this question I tried the following
> def fnc( n ):
>      print "fnc called with parameter '%d'" % n
>      return n
>
> for i in range(0,5):
>      if i%2 == 0:
>          fnc
>          next
>      print i
>
> and got the same result as the OP

> A couple of tests showed that the only important thing about the name in
> the if clause is that it is known at runtime and then it is silently
> ignored.
> However, if the name is not known/accessible at run time a 'NameError'
> is raised,
> NameError: name 'mynewfn123' is not defined
>
> On the other hand the following if clause
>      if i%2 == 0:
>          fnc    next

The results aren't surprising once you know what's going on.

If you have:

    fnc

then this name is evaluated (it refers to a function object given your 
definition. Then that value is discarded. But this:

    kljgkjhgjk

is not defined anywhere, and it can't evaluate it, raising the name 
error. While in:

    fnc()

the 'fnc' is evaluated, and then it's called (when it should give a 
parameter error as your def expects one). But

    abc def

is just a syntax error as usually two identifiers can't be adjacent 
(AFAIK) except where the first is a reserved word.

> So I have sympathy with the OP, I would expect the compiler to pick this
> up - indeed it does so for two (or more ?) unused names on a single
> line. That is unless someone can give a useful use of this behaviour or
> is there something going on under the Python hood I'm not aware of?

This one of those features I think that do have the odd use but most of 
the time just result in perplexing results or hard-to-find bugs. It 
could have been eliminated from the language (especially as many people 
aren't even aware of the possibilities) with little loss.

Someone who desperately wants to evaluate a name or expression can 
always use something like:

  def test(x):pass

  test(fnc)

for the same purpose. But this time it's obvious. (Ideally it would be a 
built-in construct to avoid the call overhead.)


-- 
Bartc



More information about the Python-list mailing list