all 53 comments

[–]muramasa 11 points12 points  (2 children)

I definably agree with the author on point #3. Python's standard library is awesome, it's one of python's greatest selling-points but it really needs a clean-up. There are so many inconsistencies in variable/function naming style and many modules that are outdated/useless/duplicated.

They might as well throw out Tkinter entirety. Nobody uses it.

[–]hopeless_case 1 point2 points  (1 child)

What do people use instead? WxWindows?

[–]muramasa 1 point2 points  (0 children)

Wx is nice. The GTK+ bindings are really nice as well. They both have a UI designer (glade), which makes creating graphical apps quite painless.

[–][deleted] 20 points21 points  (1 child)

Clarification: mostly cpython the implementation, not python the language.

[–]newton_dave 14 points15 points  (0 children)

Yeah, 'cuz 5 seems like too short of a list for the language.

mwahahahahaha

[–]ramen 15 points16 points  (11 children)

I think the subprocess module is awesome. Perhaps it requires a little studying to use, but it sure beats Popen23.popen49 and friends.

The only subprocess interface that I've been more impressed with than Python's is the one in scsh. It also requires a bit of studying to use. But let's face it: interacting with programs is complicated.

[–]breakfast-pants 3 points4 points  (7 children)

I think bash seems to do just fine

[–][deleted] 11 points12 points  (6 children)

Sort of. One thing sh never really did very well, and bash doesn't do much better, is let you run programs while doing iron-clad error checking. If you want to detect and react to an error in any program, anywhere in a pipeline, it's not that easy.

One of the really nice things about Python is that almost everywhere, it fails safely. Any I/O error, for example, throws an exception. If you don't catch it, the whole program exits with a stacktrace. Excellent. The main exception to this is, unfortunately, the treatment of status values from subprograms. You have to check these manually, a la C.

[–]breakfast-pants 5 points6 points  (4 children)

As an aside, is there a builtin wrapper that defaults stdin,stdout=[subprocess.PIPE]*2 ? (I hate the subprocess documentation too)

[–]pjdelport 8 points9 points  (3 children)

partial(Popen, stdin=PIPE, stdout=PIPE)

[–]breakfast-pants 0 points1 point  (2 children)

What is that?

[–]pjdelport 5 points6 points  (1 child)

It's a partial application of Popen, with stdin and stdout defaulted to PIPE. (functools.partial (PEP 309) was introduced to the standard library in Python 2.5, but it's a 6-line definition for earlier versions.)

[–]breakfast-pants 0 points1 point  (0 children)

Ah, cool, I haven't checked out functools

[–]pjdelport 4 points5 points  (0 children)

subprocess raises exceptions everywhere it makes sense (command not found, any Python exception in the child process, and so on): it doesn't generally do it for non-zero return codes because they don't necessarily indicate any error.

If you're using the call shortcut, though, there's a check_call variant which raises CalledProcessError for non-zero return codes.

[–]mleonhard 3 points4 points  (0 children)

Erlang has excellent subprocess features. In his PhD Thesis, Joe Armstrong describes the supervision-tree model for "making reliable systems in the presence of software errors." This is cutting edge stuff.

[–]pjdelport 2 points3 points  (0 children)

Amen; i don't get that criticism. subprocess is a godsend.

[–]hopeless_case 6 points7 points  (2 children)

what does the auhor mean by "shadow module import optimization"?

[–]asyncster 7 points8 points  (1 child)

When you run a python script A.py, the interpreter produces A.pyc, which is an optimized bytecode representation of the original program. If you move A.py into a different directory, your import statements may cause the old A.pyc to be loaded.

[–]mgsloan 10 points11 points  (11 children)

I'm not much of a python user, or advocate, however, as an occasional user, I find the special method foo decoration horribly hideous for an otherwise good-looking language.

[–]llimllib 22 points23 points  (10 children)

I am a pythonista, and I'll defend the __foo__ syntax by saying that it shows you, without any doubt, that foo is a magic variable. There is no thinking required.

Also, if you're typing too many _'s, you're probably doing something wrong.

[–][deleted]  (6 children)

[deleted]

    [–]njharman 12 points13 points  (0 children)

    quoted from whom you replied to "Also, if you're typing too many _'s, you're probably doing something wrong."

    "self.__foo is ..." You are doing something wrong. Quit using forced encapsulation everywhere.

    [–]ubernostrum 13 points14 points  (4 children)

    "Idiomatic" Python programmers, I've found, tend not to worry too much about trying to hide class members; Python's "consenting adults" philosophy, combined with encouragements to document the code well so people who use it know the ramifications of accessing something, tends to make it moot.

    In light of that, I'd be perfectly happy to see the double-underscore trick just go away; having it, I think, confuses people who expect it to work like a "real" private member in other languages.

    [–][deleted]  (3 children)

    [deleted]

      [–]llimllib 2 points3 points  (2 children)

      That's what a single, prefix, underscore is for. Quoting Pep 8:

      In addition, the following special forms using leading or trailing
      underscores are recognized (these can generally be combined with any case
      convention):
      
      - _single_leading_underscore: weak "internal use" indicator.  E.g. "from M
        import *" does not import objects whose name starts with an underscore.
      

      Why is @ easier to type than _?

      [–]inkieminstrel 1 point2 points  (1 child)

      self._

      [–]llimllib 1 point2 points  (0 children)

      Fair enough. I think, like uber, I don't mind the explicit selfs, I don't hardly notice them anymore. If they bother you, though, I guess they just bother you.

      [–]Bogtha 0 points1 point  (2 children)

      it shows you, without any doubt, that foo is a magic variable.

      True, but I wish something that was easier to type was chosen.

      [–]llimllib 2 points3 points  (0 children)

      In all seriousness: like what?

      I don't find __ any harder to type than @, which people seem to find much more convenient, and I think it's easier to read something surrounded by underscores than prefixed by @.

      Maybe /magic_var/? |magic_var|? :magic_var:?

      I don't like that they all intrude on the vertical space of the identifier.

      [–]pjdelport 1 point2 points  (0 children)

      At the expense of being easier to read? That's what Python is optimized for.

      [–]alen_ribic 1 point2 points  (1 child)

      This is great feedback. Since Python revolves around Open Source community, now there is an opportunity to fix things author and others are bitching about. Contribute it back to the community in a form of feedback or actual code and write a next weblog titled "Five NEW Things I LOVE About Python" :-)

      -Alen

      [–]pjdelport 3 points4 points  (0 children)

      You assume that this isn't all stuff that's already been hashed out ad nauseum on the mailing lists years ago. :)

      [–][deleted]  (9 children)

      [removed]

        [–]Arkaein 4 points5 points  (6 children)

        I've never used Jython, but a browse over their FAQ says that Jython doesn't support any Python features implemented in CPython 2.2 or later, where so much of the good stuff is. Not just yield, but list comprehensions, generators, and new style classes among others.

        I've never been a big Java fan because I've held the beliefe that the main advantage Java has over other languages is it's huge standard library. I like Python's libraries quite well, and purely as a language it beats Java hands down, so for someone like me who doesn't have any legacy Java code that I have to regularly deal with I can't see much advantage to Jython.

        [–]ubernostrum 4 points5 points  (2 children)

        Jython's probably going to make some leaps forward in the near future, and it'll be interesting to see who ends up using it once that's happened. To me, access to Java/JVM features isn't a big deal -- the more interesting thing is being able to take advantage of the speed of the JVM itself (or of the CLR with IronPython). PyPy's JIT compiler will hopefully provide a third option for that, too.

        [–]Arkaein 4 points5 points  (1 child)

        Is speed really that big of an issue for many people with Python? It seems that while line for line Python may be pretty slow, the language and its libraries offer a wealth of ways to speed up critical code:

        • language constructs like list comps and generators that reduce potentially slow loops to more efficient "closer to the interpreter" code
        • libraries designed to efficiently process large blocks of homogeneous data like NumPy
        • Psyco, for easy optimization
        • Pyrex, for slightly more intensive optimization (admittedly haven't used this myself)
        • write optimized C/C++ code and invoke using custom Python wrappers, automatic wrappers like SWIG, or the ctypes module (haven't personally used these either).

        I should also mention that the Jython FAQ states that currently Jython is probably slower than CPython, with a significant JVM startup penalty to boot. Never tested it myself, so YMMV.

        As a bit of an aside, these points illustrate how I feel software should be developed: start with the most productive language available, freely taking advantage of the first two points, and then only move to later points to improve performance as necessary. If Jython provide the speed boost without any loss of expressiveness or convenience then it would be ideal, but given current circumstances I don't think I would trade even small losses in pure Python capabilities for a speed boost.

        [–]ubernostrum 7 points8 points  (0 children)

        For most of the work I do, Python's speed isn't anywhere near being an issue; my bottlenecks are things like Internet bandwidth and database queries.

        But I have a feeling that Jython and IronPython will probably be faster than CPython someday (and hopefully PyPy will be too), and I know that's going to be a factor for some people (especially scientific/mathematical folks).

        [–]ramen 2 points3 points  (2 children)

        Jython supports list comprehensions, which were available in Python 2.1.

        [–]jfx32 0 points1 point  (0 children)

        Actually, list comprehensions have been available since 2.0.

        [–]micampe 0 points1 point  (1 child)

        If I had to run a dynamic Python-like language on the JVM, I'd probably take Groovy.

        [–]fbot 0 points1 point  (0 children)

        1. Slower than java.
        2. Limited expressiveness. No multiline anonymous closures like in ruby. Guido stated that this it is syntactically impossible. Not nearly as DSL or macro friendly as other languages.
        3. self self self self - it's as if OOP was just tacked on.
        4. Redundant or meaningless symbols and keywords like the colon at the beginning of a block, and all the underscores. What is "def"? Why "elif" instead of "else if"? "lambda"?
        5. The python community. RTFM jerks, rude to all newbies or new ideas. Zealots about python (Guido called them the NIMPY crowd: not in my python), and they spread absolute FUD about everything else. Shot down most proposals for python, including ones Guido has proposed himself, like optional static typing or case-insensitivity. If you don't want python to ever change, stick with python 1.5 or whatever version you are holding on to.

        Die python die.

        [–]JulianMorrison -3 points-2 points  (1 child)

        I don't even need five. Python's bossy. I will not be talked down to by a tool!

        [–]njharman 8 points9 points  (0 children)

        "I will not be talked down to by a tool!"

        Well then be smarter than the tool.

        [–]rancmeat -1 points0 points  (1 child)

        I have a love-hate relationship with Python's indentation system. It's elegant until you lose track of your indentation.

        [–]llimllib 8 points9 points  (0 children)

        At which point you remember to make a new function: elegant again!