I was reading the __init__ method of the Counter class, and saw this:
if not args:
TypeError("descriptor '__init__' of 'Counter' object "
"needs an argument")
I wasn't sure what it meant by descriptor, so I checked the python data model document and found this:
In general, a descriptor is an object attribute with “binding behavior”, one whose attribute access has been overridden by methods in the descriptor protocol: __get__(), __set__(), and __delete__(). If any of those methods are defined for an object, it is said to be a descriptor.
None of those methods seem to be present in the class definition, so why is __init_ referred to as a descriptor?
In python, all functions are descriptors (including
__init__). This is actually how they know whatselfis when they're used in a class. For example, I can define a function (foo) and then when I look at it's methods, I'll see thatfoohas a__get__method which makes it adhere to the descriptor protocol:So the terminology used there is at least accurate. It could be debated whether that's the best term to use...
I might have called it a "Bound method" instead of a descriptor, but in python3.x, the distinction between regular functions, bound methods and unbound methods becomes a little more muddy (unbound methods are regular functions in python3.x)...
Of course, I could use a different type of descriptor to initialize my
Countersubclass ...and throw an error, then the error message would be more accurate that way, but this is a pretty crazy case that I wouldn't expect to happen very frequently.
To really know what Raymond was thinking when he wrote that code, I suppose you'd have to ask him (or go spelunking in the hg commit history and hope he mentioned it in a commit message).