More thoughts on why Python doesn't see much monkey-patching

November 25, 2012

In yesterday's entry I advanced the idea that a significant part of why Python doesn't see much monkey patching (and Ruby does) is that you can't monkey patch a lot of fundamental Python classes and types because they're implemented in C. In sober hindsight, I think that I'm understating two intangibles (one of which I touched on in passing) in favour of a technical explanation.

First, I think that the effects of culture matter more than I initially thought. Culture plays a strong role in shaping how we write code in a language, both explicit in what people tell you to do and not do and implicit in things like what tutorials present and what approaches they take to solve problems. To invert the saying that you can write Fortran in any language, the reality is that people don't and culture is a good part of why.

Second is the issue of syntax. Ruby has a clear and direct syntax for adding your own methods to outside classes, while Python does not. In Python you have to go out of your way to modify a class after it's been created and the syntax is at least somewhat awkward and indirect. It's probably not longer (in lines) than the Ruby version, but it's certainly less direct and obvious. Since I'm a big believer that syntax matters I think that this can't help but have an effect in the two languages. I don't know if Ruby's syntax steers people towards monkey patching, but how it's both inobvious and a pain in Python has to steer people away from it.

Sidebar: the syntax in each language

In Ruby, monkey patching looks like this:

class SomeClass
  def newfunction
    [whatever]
  end
end

(I believe this is correct; I'm taking it from online examples, since I'm not a Ruby programmer.)

I think that this is the exact same Ruby syntax as you use when defining a full class yourself.

In Python, the equivalent is:

def newfunction(self, ...):
  [whatever]
SomeClass.newfunction = newfunction

This is shorter but less direct, involves more repetition, and doesn't clearly mark the new function as purely a class method (to be really equivalent to the Ruby version we should do 'del newfunction' to clean it out of our namespace). Full-scale lambdas would make this slightly better because then you wouldn't need to define the function separately and then glue it on to the class, but it would still look nothing like the way you define classes themselves.

Written on 25 November 2012.
« The limits of monkey patching in Python
You don't necessarily know what matters for performance »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Nov 25 22:45:42 2012
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.