in Projects, Programming, Technology

Why I hate Python

Python is a very inelegant language. Here are some things I dislike.

Python is a very common language, but it feels poorly thought out. For me, clarity over cleverness is the key selling point of a programming language, and I favor object oriented languages because it matches how I think about the world (as described in English).

Here are a few examples of how Python is an inelegant “duck tape” language. For examples, see the Gist below.

  1. The syntax for lambdas (functions as first class objects) in python is very clunky. Only a comma indicates where the block ends, and it has to fit on one line.
  2. Object oriented features feel like an afterthought. A class name is sometimes required as a function parameter in order to call a base class.
  3. Python users often abbreviate unnecessarily, making it hard to know exactly what module you’re including
  4. There are some magic built in global functions, like len() which should be member functions of the relevant classes.
  5. Standard libraries are also inconsistent in their naming conventions, like unites which uses setUp instead of set_up
  6. Again with the OO after thoughts. Why must self be passed to every instance method?
  7. Similarly, decorators like @staticmethod are used to retrofit common language features.
  8. A python dictionary (a very common data structure) has odd initialization semantics. See below for an example.
# 1. Clunky lambda syntax
numbers = [1, 2, 3]
# don't do this…
doubled = list(map(lambda n: n * 2, numbers))
# There's no way to define the end of the block except that comma. What about wrapping lines?
# better for this case
doubled = [n * 2 for n in numbers]
# 2. Confusing ways to call base method
def do_something(self):
super(MyClass, self).do_something() # MyClass not ParentClass
super().do_something() # is the same I think???
# you can call it on self if it's not overridden
# shouldn't this just be super() ???
# 3. Import abbreviation inconsistency
import numpy as np
# it's 5 letters, why does everybody abbreviate!!!
# 4. confusing magic functions len() __len__, str(), __len__ what are the other ones? I DON'T KNOW.
# Why can not do
# There are a handful of magic global functions (like len) that depend
# on an internal definition of the correct format
# it's an OO language, why doesn't list implement .length()??
# 5. libraries that use camel case (unitest setUp)
# More inconsistencies
# 6. Why must self be passed to every instance method? It's inside a class
class MyClass:
def member_method(self): # WTF!
# 6b. This is minor, but many @classmethods could probably be @staticmethods
>>> class Foo:
… @classmethod
def bar(cls, **kwargs):
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bar() takes 1 positional argument but 2 were given
# 7. similiarly, why must we use @staticmethod decorators to declare static methods?
# (it’s like OO was an afterthought)
# 8. Can’t initialize a dictionary with symbolized keys like you can in Javascript and Ruby
d = { a: "b" } # will evaluate a as if it is a variable
# in ruby, you can d = { key: value } where key is converted to the symbol "key"
# 9. Tuple initialization makes me want to cry
(1) != (1,)
# oh, and by the way you don't need parens
t = 1, # hanging comma same as t = (1,)
# and yet you can't do…
view raw hosted with ❤ by GitHub

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  1. More functions like len() and less throwback object orientation. We see the same problem but the solution is not more balkanization, it is embracing functional consistency.