147

Python seems all the rage these days, and not undeservingly - for it is truly a language with which one almost enjoys being given a new problem to solve. But, as a wise man once said (calling him a wise man only because I've no idea as to who actually said it; not sure whether he was that wise at all), to really know a language one does not only know its syntax, design, etc., advantages but also its drawbacks. No language is perfect, some are just better than others.

So, what would be in your opinion, objective drawbacks of Python.

Note: I'm not asking for a language comparison here (i.e. C# is better than Python because ... yadda yadda yadda) - more of an objective (to some level) opinion which language features are badly designed, whether, what are maybe some you're missing in it and so on. If must use another language as a comparison, but only to illustrate a point which would be hard to elaborate on otherwise (i.e. for ease of understanding)

Rook
  • 19,909
  • 50
    I think that this is a helpful subjective question, and it would be a shame to close it. – Eric Wilson Oct 29 '10 at 00:09
  • 1
    @FarmBoy - Well, I certanly tried to form it as such. Too bad the closer didn't leave a comment elaborating why he feels it is not constructive. – Rook Oct 29 '10 at 00:12
  • @Xepoch: Every language I've ever used has whitespace as tokens in its grammar. –  Oct 29 '10 at 06:00
  • @Xepoch - I ment - why he feels the question is not constructive. – Rook Oct 29 '10 at 09:28
  • 25
    There seems to be a python-fanboy here who just downvotes all anti-python answers. – zvrba Oct 29 '10 at 09:54
  • 1
    @zvrba: You get two downvotes and resort to name calling. Don't worry, you're still net positive rep. –  Oct 29 '10 at 14:25
  • 1
    @Roger: whitespace as tokens, or token delimiters? Most lexers I've worked with strip out whitespace and don't even pass it to the parser. – TMN Oct 29 '10 at 16:12
  • 2
    @TMN: That's still treating the whitespace as tokens, just not returning them — and it's exactly what Python's grammar does too. –  Oct 29 '10 at 16:22
  • 9
    @Roger: the convention on SO is to comment downvotes. Since this is a site for subjective opinions, I see no reason for downvotes, esp. w/o comments. So, I stand by my "name-calling". – zvrba Oct 29 '10 at 20:48
  • 8
    @zvrba: Downvotes still mean "not useful", just as always. –  Oct 30 '10 at 02:32
  • 2
    What exactly is an "objective opinion"? – Brendan Long Jul 23 '11 at 23:29
  • @Brendan Long: I think in this case "objective opinion" is an opinion that acknowledges its own limitations. – oosterwal Jul 24 '11 at 02:26
  • ahah, 2 years old thread revived by hackernews. The funny thing is that I tend to see many of the drawbacks listed here as a feature. Is my mind distorted ? – vincent Sep 08 '12 at 16:16

24 Answers24

108

I use Python somewhat regularly, and overall I consider it to be a very good language. Nonetheless, no language is perfect. Here are the drawbacks in order of importance to me personally:

  1. It's slow. I mean really, really slow. A lot of times this doesn't matter, but it definitely means you'll need another language for those performance-critical bits.

  2. Nested functions kind of suck in that you can't modify variables in the outer scope. Edit: I still use Python 2 due to library support, and this design flaw irritates the heck out of me, but apparently it's fixed in Python 3 due to the nonlocal statement. Can't wait for the libs I use to be ported so this flaw can be sent to the ash heap of history for good.

  3. It's missing a few features that can be useful to library/generic code and IMHO are simplicity taken to unhealthy extremes. The most important ones I can think of are user-defined value types (I'm guessing these can be created with metaclass magic, but I've never tried), and ref function parameter.

  4. It's far from the metal. Need to write threading primitives or kernel code or something? Good luck.

  5. While I don't mind the lack of ability to catch semantic errors upfront as a tradeoff for the dynamism that Python offers, I wish there were a way to catch syntactic errors and silly things like mistyping variable names without having to actually run the code.

  6. The documentation isn't as good as languages like PHP and Java that have strong corporate backings.

dsimcha
  • 17,234
  • @dsimcha: "Nested functions kind of suck in that you can't modify variables in the outer scope". Do you mean that it doesn't have closures? – Merlyn Morgan-Graham Oct 28 '10 at 23:01
  • 2
    Python does have closures. – Adam Crossland Oct 28 '10 at 23:14
  • 1
    #2: You can modify variables in the outer scope by using the nonlocal statement in python 3. #3: Python simply has no value types in that sense. Even numbers are just immutable objects. – Winston Ewert Oct 29 '10 at 00:47
  • Clarification: Python does have closures. The thing I don't like about them is that, if you have an outer function and an inner function, you can't use the inner function to modify variables local to the outer function. You only have read-only access. – dsimcha Oct 29 '10 at 00:51
  • @Winston: Thanks for the note about Python 3. I was completely unaware of this, as one of my major reasons for using Python when I use it is library support. Needless to say, this means I still use Python 2. – dsimcha Oct 29 '10 at 01:00
  • @dsimcha: The workaround for nonlocal in 2.x is annoying, but seamless: make the outer variable a list and always use var[0]. –  Oct 29 '10 at 06:02
  • 60
    @Casey, I have to disagree. The index is horrible - try looking up the with statement, or methods on a list. Anything covered in the tutorial is basically unsearchable. I have much better luck with Microsoft's documentation for C++. – Mark Ransom Oct 29 '10 at 06:14
  • 17
    About 5 - just use pyflakes. It's written to catch exactly those errors. – Alexander Solovyov Jul 12 '11 at 09:13
  • 4
    Regarding speed: with the rise of PyPy, many Python users will now be able to handle the speed problem just by using an interpreter with a built in JIT-compiler (for now, Python 3 users and users of C extension modules not handled by cpyext do not have this option). – ncoghlan Jul 13 '11 at 03:07
  • 1
    Regarding documentation: Are these comments related to the current Sphinx-based documentation? Or are they related to the pre-Sphinx documentation? The former seems unlikely, as those have excellent indices and search capability, but they would be perfectly understandable for the latter. – ncoghlan Jul 13 '11 at 03:10
  • 2
    The most valid comment in this set is number 4. Python is not a low level systems programming language. Far better to reach for an appropriate tool (such as C) and use your Python code to manage the higher level stuff. – ncoghlan Jul 13 '11 at 03:17
  • 29
    I despise the Python docs. They're prettier than most to be sure, but many times a lot of useful information is lumped into one page, like methods on strings and lists -- and all the sequence types are lumped together as well. When I search this information, I just land on a huge tome, and have to search down the page to find what I want. I also find the index on these pages hard to read, and it's sometimes difficult to tell which section I want. – Carson Myers Jul 23 '11 at 01:53
  • 3
    "Slow"? Slow at what? Compared to what? – dbr Sep 08 '12 at 12:50
  • 1
    regarding 4 - you could always code performance critical segments in c/c++ and use it from python .. – Protostome Sep 08 '12 at 15:14
  • "Slow" - have you tried PyPy? Sure it's not a silver bullet, but it sorts out those "need another language" parts. – fijal Sep 08 '12 at 16:02
  • 5
    How can distance from the metal be an argument? Did Python ever purport itself to be a systems language? – Mark Canlas Sep 09 '12 at 00:01
66

I hate that Python can’t distinguish between declaration and usage of a variable. You don’t need static typing to make that happen. It would just be nice to have a way to say “this is a variable that I deliberately declare, and I intend to introduce a new name, this is not a typo”.

Furthermore, I usually use Python variables in a write-once style, that is, I treat variables as being immutable and don’t modify them after their first assignment. Thanks to features such as list comprehension, this is actually incredibly easy and makes the code flow more easy to follow.

However, I can’t document that fact. Nothing in Python prevents me form overwriting or reusing variables.

In summary, I’d like to have two keywords in the language: var and let. If I write to a variable not declared by either of those, Python should raise an error. Furthermore, let declares variables as read-only, while var variables are “normal”.

Consider this example:

x = 42    # Error: Variable `x` undeclared

var x = 1 # OK: Declares `x` and assigns a value.
x = 42    # OK: `x` is declared and mutable.

var x = 2 # Error: Redeclaration of existing variable `x`

let y     # Error: Declaration of read-only variable `y` without value
let y = 5 # OK: Declares `y` as read-only and assigns a value.

y = 23    # Error: Variable `y` is read-only

Notice that the types are still implicit (but let variables are for all intents and purposes statically typed since they cannot be rebound to a new value, while var variables may still be dynamically typed).

Finally, all method arguments should automatically be let, i.e. they should be read-only. There’s in general no good reason to modify a parameter, except for the following idiom:

def foo(bar = None):
    if bar == None: bar = [1, 2, 3]

This could be replaced by a slightly different idiom:

def foo(bar = None):
    let mybar = bar or [1, 2, 3]
  • Immutable variables can be done with class attributes -- see this article, at the beginning, the section "Bindings". – Abbafei Mar 17 '11 at 22:39
  • 6
    I so so wish Python had a "var" statement. Besides the (very good) reason you state, it would also make it a lot easier to read the code because then you can just scan over the page to spot all the variable declarations. – jhocking Jul 11 '11 at 23:19
  • 25
    It is as if the python developers ignored the lessons of the past. Not declaring variables, not declaring functions, is a mistake first made in the 1950s. Those hard to find bugs that resulted from a hard to spot typo were amazingly enough first made in the 1950s. This language mistake has been made (and later corrected) time and time again. Declaring variables is not a huge burden. It has saved my butt multiple times. I inevitably use strict; and use warnings; in perl on a script of any size. Python has stripped the developer of far too many debugging aids. – David Hammen Jul 19 '11 at 00:00
  • 19
    @David, To be fair to python, it will raise an exception if you try to access a variable which has not been assigned to. Many of the languages which lack declarations would return some sort of default value. As a result, Python's version is much less problematic then those ones. – Winston Ewert Jul 23 '11 at 23:58
  • I can only imagine the features let and var with some kind of notation to enable strict checks otherwise you break all existing code. That notation could work on a function/class/module level to note that checks should be enforced. – Karoly Horvath Jul 24 '11 at 00:20
  • I can't edit, but let y # Error: Declaration of read-only variablexwithout value uses the wrong var (x should by y) – Martijn Jul 24 '11 at 00:42
  • 1
    @yi_H The proposal wasn’t meant to be backwards compatible – or even a real proposal. The question was, “what are the drawbacks of Python” … well, not having var and let (or a similar mechanism) is a drawback. Put differently: had I been the designer of Python, I would have done something like this. That said, future versions could include this when you load a special package (similar to __future__). Say, import strict. This won’t happen though, since it requires syntactical hacks … – Konrad Rudolph Jul 24 '11 at 13:48
  • Is there any popular dynamic language out there which is using these strict checks? I think Perl is the only one, but gets less and less popular. PHP and Ruby doesn't do it and Javascript is the worst of all of them since it puts the non-declared variables into global scope, which can lead to very ugly bugs. I'm more or less satisfied with the rest (non JS) languages, if you ever write test-cases to your code (which you should do anyway) you will catch 99% of the typos. I'm not saying I wouldn't enjoy a strict mode for some tasks but it's probably a feature I can live without. – Karoly Horvath Jul 24 '11 at 15:38
  • @yi_H Not that I’m aware of. I’d use it in a heartbeat – well, not Perl since that is just FUBAR. I do use Perl but I don’t relish it. As for test cases: obviously these help but I hate writing manual tests for issues that the compiler should (and could!) catch for me. This is what a type system is there for, after all. My C++ projects have (near) 100% test coverage but I don’t have to write redundant tests to get rid of errors that the type system will catch. – Konrad Rudolph Jul 24 '11 at 15:47
  • @David is right about declarations, but there is an argument that most languages that require those declarations go too far the other way. There are interesting middle-grounds in static typing, and some are certainly possible (don't know any implementation) for dynamic languages. But it's not that surprising that people rejecting one extreme jump straight to the opposite extreme. –  Jul 25 '11 at 22:50
  • It's perhaps less disruptive to use const for read-only variables. – Seun Osewa Nov 30 '11 at 18:12
  • @Seun I don’t think so. On the contrary. – Konrad Rudolph Nov 30 '11 at 18:48
  • 3
    +1 For adding better 'functional-like' programming abilities. – Evan Plaice May 02 '12 at 14:33
  • @WinstonEwert - Perhaps but then you're just hoping that the block of code which references that variable happens to be called and yo can catch it at runtime... – Basic May 29 '13 at 14:38
  • @Basic, if your testing has never run that block of code chances are its broken in more ways than just having a misspelled variable name. – Winston Ewert May 29 '13 at 14:44
  • 1
    @WinstonEwert So now we need to run the whole set of unit tests to find a typo... – Basic May 29 '13 at 15:03
  • @Basic, the point of my comment was that raising an exception is way better than treating all undeclared variables as NULL. As you'll see in my comment, I described it as much less problematic. I was reacting to the previous comment that claimed that Python was just repeating the same mistake as older languages, which I think was over-simplifying the issue. – Winston Ewert May 29 '13 at 16:24
  • 1
    @Basic, actually, it is possible to detect many of those typos without actually running the code. Pylint, pyflakes, and pychecker can all statically analyze code and detect those errors. – Winston Ewert May 29 '13 at 16:26
44

My main complaint is threading, which is not as performant in many circumstances (compared to Java, C and others) due to the global interpreter lock (see "Inside the Python GIL" (PDF link) talk)

However there is a multiprocess interface that is very easy to use, however it is going to be heavier on memory usage for the same number of processes vs. threads, or difficult if you have a lot of shared data. The benefit however, is that once you have a program working on with multiple processes, it can scale across multiple machines, something a threaded program can't do.

I really disagree on the critique of the documentation, I think it is excellent and better than most if not all major languages out there.

Also you can catch many of the runtime bugs running pylint.

dbr
  • 161
cmcginty
  • 729
  • 2
    +1 for pylint. I was unaware of it. Next time I do a project in Python, I'll try it out. Also, multithreading seems to work fine if you use Jython instead of the reference CPython implementation. OTOH Jython is somewhat slower than CPython, so this can partially defeat the purpose. – dsimcha Oct 29 '10 at 00:48
  • 3
    Threading is not well supported? The threading libraries have been in there since before 2.1. – rox0r Dec 18 '10 at 07:16
  • 2
    I know there is threading support, but compared to Java or C, the GIL will really lower your performance. That is why the multiprocessing module is preferred over threading. – cmcginty Dec 20 '10 at 23:15
  • 2
    The documentation is good if you can manage to find it. Googling Java classes is much easier than Python. – Brendan Long Jul 23 '11 at 23:32
  • @Casey I've clarified the wording in the answer, since threading is supported, just exhibits some weird performance (added a reference and a few links to docs too) – dbr Sep 08 '12 at 13:05
  • This is really more a critique of the interpreter than the language. My understanding is that Jython bypasses the GIL and uses Java Threads, which typically are system threads. – philosodad Sep 08 '12 at 18:32
  • Nevertheless so many real world Python app has module dependencies that tie it to CPython and native CPython extensions, that JYthon is immaterial to real Python use. Does Mercurial run in Jython, for instance? – Warren P Sep 11 '12 at 03:17
28

Arguably, the lack of static typing, which can introduce certain classes of runtime errors, is not worth the added flexibility that duck typing provides.

Jacob
  • 382
  • 5
    This is correct, though there are tools like PyChecker which can check for errors a compiler in languages like C/Java would do. – Oliver Weiler Oct 28 '10 at 23:42
  • 24
    Dynamic typing is a conscious design decision, not a drawback. – missingfaktor Nov 11 '10 at 12:18
  • 14
    Its the same as saying Java's weakness is lack of dynamic typing. – MAK Nov 11 '10 at 13:36
  • 12
    @missingfaktor, @MAK, obviously duck typing was an intended feature. But most design decisions introduce objective benefits and drawbacks. The added code flexibility is a benefit of dynamic typing, and the additional classes of potential runtime errors is a drawback. The subjective part is whether the feature is worth it. – Jacob Nov 11 '10 at 16:27
  • Lack of static typing introduces runtime errors? – rox0r Dec 18 '10 at 07:17
  • 6
    Lack of static typing makes it easier for programmers to write code that has runtime errors. In C#, int foo = 4; Console.Write(foo.Length); doesn't compile, so the error "Int32 doesn't have a property Length" cannot accidentally make its way into published software. In python, unless you run optional secondary tools to look for errors like that, code that accesses non-existing members of objects can go undetected until it ends up causing runtime errors. – Jacob Dec 18 '10 at 16:29
  • 1
    See this for a feature similar to "static types" for Python 3, and this for Python 2. – Abbafei Mar 17 '11 at 22:49
  • This seems to be more a criticism of scripting languages in general. Haskell types work like Python's (you don't have to declare types), and it figures out what types are at compile-time (basically everything is generic unless you say otherwise). Even if Python made you declare types like C, you still wouldn't know if they were right until you try to run it. – Brendan Long Jul 23 '11 at 23:35
  • 2
    If a project's testing is so poor that int foo = 4; Console.Write(foo.Length) could make it into release versions if the compiler allowed it, then I guarantee that the project's released versions contain many many more bugs, whether or not it was written in a statically typed language. – Ben Jul 24 '11 at 06:21
  • 4
    @Ben: That was a trivial example. What if the declaration was in one module and the use was in another, and this usage is a corner case that's only accessed under certain circumstances by one user? But that one user happens to be one of your biggest clients, and this functionality is critical to their workflow, and if you don't fix it your program will fail UAT? (Purely hypothetical, but based on plenty of real experience.) There's a reason why people don't tend to write large, serious programs in dynamic languages. Without a compiler and a static type system, they grow unmanageable quickly. – Mason Wheeler Jul 25 '11 at 22:29
  • @Mason Wheeler: There will always be bugs that no static analysis can catch. This is true in languages with very strong static type systems, such as Haskell and Mercury, and it's even more true in commonly used statically languages such as Java and C# that have somewhat weaker type systems. If you write serious code that needs to have serious assurance of reliability, you must test it. If your testing is not good enough to find the subset of bugs that a type-checking compiler would find, it is not good enough to give very good assurances that there aren't other kinds of bugs either. – Ben Jul 26 '11 at 01:55
  • I will buy the argument that dynamic typing makes it take a bit more effort to find some bugs (although you could also argue that it's easier to debug in languages where you have more flexibility, so it's not necessarily true). But in practice projects written in dynamic languages are not more buggy than ones written in static languages. Poorly tested projects have many bugs whether the language is dynamically or statically typed. – Ben Jul 26 '11 at 02:05
  • -1 runtime errors are a reality whether or not your language is statically-typed or dynamically-typed. The compiler itself only checks syntactic errors, for everything else there's unit testing. I would trade polymorphism, object boxing, OOP relationship abuse, and other related boilerplate (ie used to make square pegs fit in round holes) for duck typing any day. – Evan Plaice May 02 '12 at 14:28
  • 3
    False, Evan. Compilers don't just check for syntactic errors; they'll also detect if you're accessing a member that doesn't exist (for example, if you mistyped the name of a property) or if you're attempting operations on a value that are not supported by the type (like trying to call something that's not a function). There's a huge class of errors that will never become runtime errors in statically-typed languages because the code won't compile. Don't deny this fact and downvote; as I said, it's arguable whether the reduced safety is worth the added power; some prefer it that way. – Jacob May 02 '12 at 16:44
  • @Brendan Long: I do not think your statement is correct: You cannot have type errors at runtime in Haskell. Either the compiler can figure out the type of an expression, or it can't. In the former case you will not have a runtime type error. In Python you can have type errors at runtime. Or did I understand it wrong? – Giorgio Jun 27 '12 at 19:01
  • 1
    @Giorgio That's exactly my point. In compiled languages (like Haskell) you can get type errors at compile time, but scripting languages (like Python) don't have a "compile time" so you can only get type errors at runtime. – Brendan Long Jun 27 '12 at 19:11
  • But if you could declare variable types or function signatures you could also perform some static type checking I guess. – Giorgio Jun 27 '12 at 19:34
  • If dynamic typing was such a hugely problematic feature, people would stop implementing it in scripting languages. The tradeoff is performance. That is all. Everything else you hear is abject cowardice on the part of devs who've never tried it a different way or who simply can't imagine what it means to actually pay attention to the flow of data through your app. – Erik Reppen Nov 29 '12 at 06:35
  • @ErikReppen, performance isn't the only tradeoff. Having developed with Python, I know firsthand that development aids such as refactoring tools and code autocompletion are hampered because of the lack of static typing, and you also lack build-time type checking.

    Nobody's saying that dynamic typing is "hugely problematic." There are just language tradeoffs.

    – Jacob Nov 29 '12 at 23:53
  • I'd kill to have decent .Net-level intellisense in PyDev. Unfortunately, 99% of the time, PyDev doesn't know what type it's dealing with (and even if it does, what properties/methods that type may have are impossible to determine) which means I spend an inrdinate amount of time remembering/typing names ala customer.addresses.objects.. And @ErikReppen Smooth argument - people who disagree with you must be cowards – Basic May 29 '13 at 14:50
  • @Basic Fair enough. I was grumpy at our codebase at the time. But the problem, IMO, is the way people think they're supposed to write code. I don't have your problem when I make the switch to static and I don't typically run into a lot of type issues. People can and do write complex large-scale web apps with dynamic languages and they don't have to rethink the way they write code to do the same in static languages. If static types protect you from anything they protect from learning how not to write code that makes you paranoid about your data being touched by 10,000 different sets of hands. – Erik Reppen May 29 '13 at 19:20
27

I think the object-oriented parts of Python feel kind of "bolted on". The whole need to explicitly pass "self" to every method is a symptom that it's OOP component wasn't expressly planned, you could say; it also shows Python's sometimes warty scoping rules that were criticized in another answer.

Edit:

When I say Python's object-oriented parts feel "bolted on", I mean that at times, the OOP side feels rather inconsistent. Take Ruby, for example: In Ruby, everything is an object, and you call a method using the familiar obj.method syntax (with the exception of overloaded operators, of course); in Python, everything is an object, too, but some methods you call as a function; i.e., you overload __len__ to return a length, but call it using len(obj) instead of the more familiar (and consistent) obj.length common in other languages. I know there are reasons behind this design decision, but I don't like them.

Plus, Python's OOP model lacks any sort of data protection, i.e., there aren't private, protected, and public members; you can mimic them using _ and __ in front of methods, but it's kind of ugly. Similarly, Python doesn't quite get the message-passing aspect of OOP right, either.

mipadi
  • 7,503
  • 17
    The self parameter is merely making explicit what other languages leave implicit. Those languages clearly have a "self" parameter. –  Oct 29 '10 at 06:08
  • 13
    @Roger Pate: Yes, but that explicit need for "self" is kind of annoying (and, I would argue, a leaky abstraction). It also didn't come about as a deliberate design decision, but due to Python's "weird" scoping rules. I can't find the article quickly, but there's a email posting from Guido van Rossum that explains nicely why the "self" parameter is required. – mipadi Oct 29 '10 at 12:54
  • @mipadi: It's less leaky than you might think; in some ways it's more consistent. A few extreme examples of that in the previous comment's link. Compare to the attitude in C++ that free functions are extension methods (I can search for the blog post from a prominent programmer about that, if you like) and how extension methods (as a formal feature) in some other languages have a fixed first parameter of "this". –  Oct 29 '10 at 13:08
  • 2
    @Roger Pate: In object-oriented languages, passing the target as the first parameter could still be considered an implementation detail. My point, though, isn't whether it's a good idea or not; the point is that in Python, it's not due to a conscious design decision, but rather to work around warts in the scoping system. – mipadi Oct 29 '10 at 14:08
  • @mipadi: This question is asking about drawbacks, if your point isn't that it's a bad idea, what is the purpose of this answer? Perhaps that's what I was feeling from your answer initially (and why I downvoted): you aren't justifying why this is a bad idea because you apparently never intended it that way? –  Oct 29 '10 at 14:11
  • 2
    @Roger Pate: I expressly said in my answer that the need to pass self as the first parameter was a symptom that Python's OOP side wasn't well-planned, and that it was due to Python's somewhat-broken scoping rules. (For the record, I don't think explicitly passing self is a good idea, but that's not the point.) I also elaborated in my answer that it's use is not a design decision, but due to Python's scoping rules. Not sure how I could be more clear. – mipadi Oct 29 '10 at 14:16
  • 3
    @mipadi: The update has better reasoning (so I'll remove the downvote), but if you view len as an operator which you overload, it's more OO in Python. Would love to see an example or reasoning on how Python gets message-passing wrong. –  Oct 29 '10 at 14:23
  • 1
    I believe http://python-history.blogspot.com/2009/02/adding-support-for-user-defined-classes.html is the article that is being referred to. The issue essentially is that without variable decelerations its impossible to know where a value should be stored on assignment. So it is certainly true that this was produced by the design of the rest of the language. I don't see that as a bad thing, simply the fact that language design has trade offs. (Although in this case I think the explicitness is a gain not a loss) – Winston Ewert Oct 29 '10 at 15:50
  • 8
    Explicit self is an outgrowth of the fact that methods are just functions (and, as Winston noted, implicit local variable declarations). You're free to not like that design decision, but calling OOP "bolted on" in a language where everything is accessible as an object at runtime is silly. – ncoghlan Jul 13 '11 at 03:22
  • 1
    In Python, everything is an object. object is an object. type is an object. When you declare a class, that class is itself an object, and is an instance of a class! I can't think of a language with a more complete "everything is an object" world view. – Ben Jul 24 '11 at 06:31
  • @Ben: Well, there is, for example, Ruby, in which everything is not only an object, but, unlike Python, the syntax for invoking methods is consistent. – mipadi Sep 22 '11 at 17:15
  • 1
    @mipadi: everything except functions.... Which brings about the necessity of procs, blocks and lambdas, which imo is Ruby's biggest wart. – limscoder Sep 09 '12 at 02:43
  • This is likely the top or close to top answer. Threading would be the only thing I'd place as a competing complaint. – Rig Sep 10 '12 at 13:10
19

Things I don't like about Python:

  1. Threading (I know its been mentioned already, but worth mentioning in every post).
  2. No support for multi-line anonymous functions (lambda can contain only one expression).
  3. Lack of a simple but powerful input reading function/class (like cin or scanf in C++ and C or Scanner in Java).
  4. All strings are not unicode by default (but fixed in Python 3).
MAK
  • 1,083
  • 5
    Regarding (2), I think this is offset by the possibility to have nested functions. – Konrad Rudolph Dec 26 '10 at 12:13
  • 3
    @KonradRudolph My main qualm with nested functions instead of multi-line lambdas is the reading order gets swapped. – CookieOfFortune Sep 08 '12 at 15:36
  • Regarding (3), what about input() (called raw_input in python 2), and sys.stdin? – wkschwartz Sep 08 '12 at 16:09
  • @CookieOfFortune: OTOH, if you make the inline lambda a full-blown function, it can be unit-tested and reused elsewhere. If you need complicated lambdas, they may end up biting you later. – rbanffy Sep 08 '12 at 16:34
  • @rbanffy Sure, but it would just be nice to have the option of a middle ground. – CookieOfFortune Sep 08 '12 at 17:48
  • unicode seems so much easier in Python than every other language I've worked with, which languages offer unicode by default, and doesn't it get in the way when most of your strings are simple byte arrays anyway? Isn't it easier to have to explicitly use unicode vs having to explicitly use byte arrays?
  • – limscoder Sep 09 '12 at 02:50
  • 2
    @wkschwartz: raw_input and 'sys.stdin' are pretty barebones. They don't support getting formatted input (e.g. something like "%d:%d:%d" % (hour, minute, sec) to read in time). So far Python does not have anything approaching the functionality of scanf(in C) or Scanner(Java). – MAK Sep 09 '12 at 04:47
  • 2
    @limscoder: All strings are unicode by default in Java. I don't see a good reason to have separate str and unicode classes. IMHO, strings and arrays of bytes should not be represented by the same abstraction. A string class should be for storing and manipulating text - whose internal representation we don't really care about. We should not want to do things like truncate/replace/delete/insert at a specific byte within a string - we want to do this at a specific character. Its easy to forget the distinction and have your code blow up when fed non-english input. – MAK Sep 09 '12 at 05:07
  • 1
    @limscoder: if you want to see easy unicode, try Tcl. I had to switch from Tcl to Python a few years back, and boy was I surprised at how primitive python's unicode support is in comparrison. It's truly invisible in Tcl, and a major pain in python. – Bryan Oakley Sep 10 '12 at 11:00
  • for the things your answer states it is too short to the point of being misleading while not being entirely incorrect. C++/Java are better than Python for string parsing? wtf. – jfs Jun 02 '13 at 19:23
  • @J.F.Sebastian: I think my answer states clearly what is lacking here. Python does not provide something as simple as scanf for reading formatted text. Where exactly is this misleading? – MAK Jun 02 '13 at 21:43
  • Python is not C. You could use string manipulations, regular expressions, specialized parsers out of the box. There are several modules that provide scanf-like functionality but none are popular. So technically you're correct: there is no scanf in stdlib but it is misleading to suggest that it makes the input handling in Python more complex or less powerful compared to the alternatives. – jfs Jun 02 '13 at 23:25
  • @J.F.Sebastian: It certainly isn't less powerful, but I disagree that it isn't more complex. My point is, having something like Scanner or scanf would make life simpler when reading simple formatted input - not saying it is impossible or even too hard to do this in Python right now. – MAK Jun 03 '13 at 09:46