Is OOP Pythonic?

3 points by wheelerof4te ↗ HN
I have had this dilemma ever since I started programming in Python 3 years ago.

I am a strong believer in procedural programming, with some functional goodness thrown in. My argument is that procedures and functions complement each other well. Procedures change state, while functions produce new state. Dennis Ritchie figured this out almost 50 years ago and granted us C. People loved and still love C for it's simplicity and clear separation of data and procedures. You were granted a way to introduce your own structured data types, and that simple but powerful feature was enough for all kinds of complex data representations.

So what all this has to do with Python? Well, Python has a builtin way of implementing structures, but because of it's dynamic nature, that representation in the end boils down to simple key-value pairs -> dictionaries. So, why Python programmers prefer making classes when the language has dictionaries? Not only is using builtin types faster, it should also be more Pythonic, since you are exploiting one of the core features of Python: it's dynamic nature. Just look at LOAD_ATTR opcode, it's insane how slow that thing is.

If it quacks like a duck...or better yet, if it has a key, it is easy to check. So why not use it more?

6 comments

[ 5.6 ms ] story [ 27.7 ms ] thread
So, why Python programmers prefer making classes when the language has dictionaries?

Bound methods. And yes, if you don't drive it into the ground, inheritance can be useful, also.

Both useful, yes. But consider this:

  my_instance = SomeClass(args)

  my_instance.method()
vs

  my_dict = some_mod.thing_new(args)

  some_mod.function(my_dict, args)
These are semantically the same things. If you don't believe me, consider this is the same as above class example:

  SomeClass.method(my_instance)
As for the inheritance, you could theoretically insert the "parent" dictionary inside the "child" dictionary and just create a new module for child "methods". But that would be too convoluted and surely unpythonic.

My argument goes against OOP, so I would just ignore inheritance.

If objects are represented as dictionaries, how do you do a type check, like this object obj is a Window (and not something else, like a Font, or Image)? Test for the presence of 17 properties that are the telltale marks of a Window?

Why have function parameters and local variables? Everything can be a dictionary. There can be an args and locals which are built-in sybmols. When a function executes, you access keys in args to get it arguments, and keys in locals to work with local variables. For more nuance, there can be fixargs which is a vector and keyargs which is a dict. If you want a new local variable, you just insert a new key into locals.

We can stick an ad-hoc type convention, e.g. every dictionary used as an object has to have a "type" key and so forth. Doable, but not too appetizing.
In a way, almost everything in Python is a dictionary. But I see your point.

API design would be tricky to do without classes, but what is stopping us from making typed dictionaries? If I'm not mistaken, something similar already exists in stdlib.

Anyway, my intention was not to argue future design of Python. I just believe that writting classes complicates the overal program design, leading to unpythonic code.

Yes, there is a really stupid thing you can do in Python, which is to add a property to an existing object, which is then available via obj.name syntax. It's not declared in a class or anything.