[Python-ideas] Python Reviewed

Chris Angelico rosuav at gmail.com
Mon Jan 9 08:31:42 EST 2017


On Mon, Jan 9, 2017 at 10:25 PM, Simon Lovell <simon58500 at bigpond.com> wrote:
> Python Reviewed
>
> Having used a lot of languages a little bit and not finding satisfactory
> answers to these in some cases often asked questions, I thought I'd join
> this group to make a post on the virtues and otherwise of python.

I think this thread belongs on python-list at python.org, where you'll
find plenty of people happy to discuss why Python is and/or shouldn't
be the way it is.

A couple of responses to just a couple of your points.

> The Good:
>     Syntactically significant new lines
>     Syntactically significant indenting

>
> The Bad:
>     No end required for if/while/for blocks. This is particularly a problem
> when placing code into text without fixed width fonts. It also is a
> potential problem with tab expansion tricking the programmer.

If indentation and line endings are significant, you shouldn't need
end markers. They don't buy you anything. In any case, I've never
missed them; in fact, Python code follows the "header and lines"
concept that I've worked with in many, MANY data files for decades
(think of the sectioned config file format, for example).

>     This code block doesn't compile, even given that function "process"
> takes one string parameter:
>         f=open(file)
>         endwhile=""
>         while (line=f.readline())!=None:
>             process(line)
>         endwhile
>
>         I note that many solutions have been proposed to this. In C, it is
> the ability to write "while(line=fgets(f))" instead of
> "while((line=fgets(f))!=NULL)" which causes the confusion. No solutions have
> been accepted to the current method which is tacky:
>         f=open(file)
>         endwhile=""
>         endif=""
>         while True:
>             line=f.readline
>             if line = None:
>                 break
>             endif
>             process(line)
>         endwhile

Here's a better way:

for line in open(file):
    process(line)

If you translate C code to Python, sure, it'll sometimes come out even
uglier than the C original. But there's often a Pythonic way to write
things.

>     Inadequacy of PEP249 - Python Database Specification. This only supports
> dynamic SQL but SQL and particularly select statements should be easier to
> work with in the normal cases where you don't need such statements. e.g:
>         endselect=""
>         idList = select from identities where surname = 'JONES':
>                 idVar         = id
>                 forenameVar    = forename
>                 surnameVar    = surname
>                 dobVar        = dob
>         endselect
>
>         endfor=""
>         for id in idList:
>             print id.forenameVar, id.dobVar
>         endfor

You're welcome to propose something like this. I suspect you could
build an SQL engine that uses a class to create those bindings -
something like:

class people(identities):
    id, forename, surname, dob
    where="surname = 'JONES'"

for person in people:
    print(person.forename, person.dob)

Side point: "forename" and "surname" are inadvisable fields.
http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/

>         One of the major problems with the status quo is the lack of named
> result columns. The other is that the programmer is required to convert the
> where clause into a string. The functionality of dynamic where/from clauses
> can still be provided without needing to rely on numbered result columns
> like so:
>         endselect=""
>         idList = select from identities where :where_clause:
>             id        = id
>             forename    = forename
>             surname        = surname
>             dob        = dob
>         endselect

That's easy enough to do with a namedtuple.

>     Variables never set to anything do not error until they are used, at
> least in implementations of Python 2 I have tried. e.g.
>         UnlikelyCondition = False
>         endif=""
>         if UnlikelyCondition:
>             print x
>         endif
>
>         The above code runs fine until UnlikelyCondition is set to True

That's because globals and builtins could be created dynamically. It's
a consequence of not having variable declarations. You'll find a lot
of editors/linters will flag this, though.

>     Changing print from a statement to a function in Python 3 adds no
> positive value that I can see

Adds heaps of positive value to a lot of people. You simply haven't
met the situations where it's better. It's sufficiently better that I
often use __future__ to pull it in even in 2.7-only projects.

>     Lack of a single character in a method to refer to an attribute instead
> of a local variable, similar to C's "*" for dereferencing a pointer

Ehh. "self." isn't that long. Python isn't AWK.

>     Inability to make simple chained assignments e.g. "a = b = 0"

Really? Works fine. You can chain assignment like that.

>     Conditional expression (<true-value> if <condition> else <false-value>)
> in Python is less intuitive than in C (<condition> ? <true-value> :
> <false-value>). Ref PEP308. Why BDFL chose the syntax he did is not at all
> clear.

I agree with you on this one - specifically, because the order of
evaluation is "middle then outside", instead of left-to-right.

> The Ugly:
>     Persisting with the crapulence from C where a non zero integer is true
> and zero is false - only ever done because C lacked a boolean data type.
> This is a flagrant violation of PEP 20.2 "Explicit is better than implicit"
> and should be removed without providing backwards compatibility.

In Python, *everything* is either true or false. Anything that
represents "something" is true, and anything that represents "nothing"
is false. An empty list is false, but a list with items in it is true.
This is incredibly helpful and most definitely not ugly; Python is not
REXX.

ChrisA


More information about the Python-ideas mailing list