== The argument about unbound methods versus functions As mentioned in [[How functions become bound or unbound methods HowFunctionsToMethods]], in Python 2 when you access a function on a class (eg you do _cls.func_) it becomes an 'unbound method'. In Python 3 this is gone, as [[Peter Donis http://blog.peterdonis.com/]] mentioned in a comment on that entry; if you do _cls.func_ you get back the plain function. I'm not entirely sure how I feel about this, so let's start by asking a relevant question: what's the difference between an unbound method and the underlying function? The answer is that calling an unbound method adds extra type checking on the first argument. When _cls.func_ is an unbound method and you call it, the first argument must be an instance of _cls_ or a subclass of it (ie, something for which _isinstance()_ would return _True_). If it isn't you get a _TypeError_ (much like the ones we saw [[back here MetaclassDuckTypingImpossible]]). Calling the function directly has no such requirement; you can feed it anything at all, even though as a class method it's probably expecting an instance of the class as its first argument. I'll admit that it's an open argument whether this type checking is a good thing or not. It's certainly atypical for Python and the conversion from a plain function into an unbound method is a bit surprising to people. There aren't that many situations in Python where making something an attribute of a simple class magically changes it into something else; normally you expect '_A.attr = something; A.attr_' to give you '_something_' again. The argument in defense of the checking is that it's a useful safety measure for functions that are almost certainly coded with certain assumptions and directly calling class methods on the class is not exactly a common thing. Now that I've written this entry, I can see why Python 3 took unbound methods out. They might be handy but they're not actually essential to how things work (unlike bound methods) and Python's mechanics are mostly about what actively has to be there. I guess my view is now that I don't mind them in Python 2 but I doubt I'm going to miss them in Python 3 ([[if I ever do anything with Python 3 Python3NewCodeII]]).