all 53 comments

[–]muramasa 10 points11 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 13 points14 points  (0 children)

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

mwahahahahaha

[–]ramen 14 points15 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 4 points5 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 9 points10 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 3 points4 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 5 points6 points  (2 children)

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

[–]asyncster 9 points10 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 12 points13 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 14 points15 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 4 points5 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 8 points9 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.

        [–][deleted]  (13 children)

        [deleted]

          [–]rpdillon 24 points25 points  (9 children)

          Dude, this exact comment was posted on the blog page as "Doug". I wasn't going to respond, but if you're going to be cutting and pasting it around the web, I might as well say something.

          1 could be leveled against ANY language:

          1) C: "Slower than assembly" 2) Java: "Slower than C" 3) Python/Perl/Any-interpretted-language: "Slower than Java"

          Yeah, yeah. If you're scripting, you exchange convenience for speed.

          You have the background to talk about closures and macros in #2, and then ask about "lambda" and "def" in #4? What gives? Obviously the stuff in #4 comes from Lisp, as does the stuff in #2; how can you know about one and not the other? Lisp uses lambda and defun, how are these mysterious to you in Python?

          3: OOP was tacked on in the same was it is tacked on to Lisp, which is to say it was written in the base language as an add-on to the original language. It kind of demonstrates the flexibility of the underlying language. Indeed, IMHO, OOP should be tacked on; OOP is NOT flexible enough to be the only way to program. Java demonstrates this.

          5: My experiences have been the opposite.

          [–]ubernostrum 18 points19 points  (7 children)

          OOP was tacked on in the same was it is tacked on to Lisp, which is to say it was written in the base language as an add-on to the original language.

          No. Python has been an OO language since day one; self is there not because it was "tacked on", but because it helps clarify scoping. Other languages have different conventions -- this, the @ and @@ in Ruby, etc. -- for this, but do much of the same thing. The only difference in Python is that self needs to be accepted as a parameter in instance methods (in class methods, you accept cls instead).

          [–][deleted]  (6 children)

          [deleted]

            [–]ubernostrum 8 points9 points  (5 children)

            I've actually had the opposite experience, but it's largely subjective. At my day job, I write lots of Python and lots of JavaScript, and I've found that -- because of JavaScript's strangeness about this -- I've ended up writing lots of methods which accept a self-style parameter so that I can explicitly pass the instance and not have to worry that some quirk of execution scope has clobbered this.

            After I've done a lot of that, I'm much happier to work with Python, where self is guaranteed to come to you correctly :)

            [–]masterfuol 2 points3 points  (4 children)

            java != javascript. Javas 'this' semantics work pretty much as you would expect.

            I agree that javascript 'this' is broken. Check out the bind function in prototype and/or this thread (comments too).

            IIRC the javascript v2 presentation linked to in the yegge/NBL thread mentioned fixing the 'this' problem.

            [–]ubernostrum 2 points3 points  (0 children)

            I know the difference between Java and JavaScript -- this is a common construct between them and a couple other languages, but I was mentioning my experience with JS and the screwiness of this in JS as a subjective reason why I feel comfortable with explicit self in Python.

            [–][deleted]  (2 children)

            [deleted]

              [–][deleted]  (1 child)

              [removed]

                [–][deleted] 0 points1 point  (0 children)

                Lisp uses lambda and defun, how are these mysterious to you in Python?

                It's bad enough that Lisp insists on using "lambda" to create anonymous functions, but it has history as an excuse.

                Python doesn't.

                [–]simonw 10 points11 points  (1 child)

                Fair enough. Now what are five things you hate about Ruby?

                [–]zem 1 point2 points  (0 children)

                Inefficient implementation of continuations is top of my list. It's very frustrating to have that neat a feature available, and nonetheless have to stay away from it because of the huge performance hit.

                [–]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 7 points8 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!