I came across this question with similar confusion, and after I answered it for myself it seemed prudent to report my findings here for prosperity.
As ThiefMaster already pointed out, the "owner" parameter makes possible constructions like a classproperty. Sometimes, you want classes to have methods masked as non-method attributes, and using the owner parameter allows you to do that with normal descriptors.
But that is only half the question. As for the "read-only" issue, here's what I found:
I first found the answer here: http://martyalchin.com/2007/nov/23/python-descriptors-part-1-of-2/. I did not understand it at first, and it took me about five minutes to wrap my head around it. What finally convinced me was coming up with an example.
Consider the most common descriptor: property. Let's use a trivial example class, with a property count, which is the number of times the variable count has been accessed.
class MyClass(object):
def __init__(self):
self._count = 0
@property
def count(self):
tmp = self._count
self._count += 1
return tmp
@count.setter
def setcount(self):
raise AttributeError('read-only attribute')
@count.deleter
def delcount(self):
raise AttributeError('read-only attribute')
As we've already established, the owner parameter of the __get__ function means that when you access the attribute at the class level, the __get__ function intercepts the getattr call. As it happens, the code for property simply returns the property itself when accessed at the class level, but it could do anything (like return some static value).
Now, imagine what would happen if __set__ and __del__ worked the same way. The __set__ and __del__ methods would intercept all setattr and delattr calls at the class level, in addition to the instance level.
As a consequence, this means that the "count" attribute of MyClass is effectively unmodifiable. If you're used to programming in static, compiled languages like Java this doesn't seem very interesting, since you can't modify classes in application code. But in Python, you can. Classes are considered objects, and you can dynamically assign any of their attributes. For example, let's say MyClass is part of a third-party module, and MyClass is almost entirely perfect for our application (let's assume there's other code in there besides the code for count) except that we wished the count method worked a little differently. Instead, we want it to always return 10, for every single instance. We could do the following:
>>> MyClass.count = 10
>>> myinstance = MyClass()
>>> myinstance.count
10
If __set__ intercepted the call to setattr(MyClass, 'count'), then there would be no way to actually change MyClass. Instead, the code for setcount would intercept it and couldn't do anything with it. The only solution would be to edit the source code for MyClass. (I'm not even sure you could overwrite it in a subclass, because I think defining it in a subclass would still invoke the setattr code. But I'm not sure, and since we're already dealing with a counterfactual here, I don't really have a way of testing it.)
Now, you may be saying, "That's exactly what I want! I intentionally did not want my user to reassign attributes of my class!" To that, all I can say is that what you wanted is impossible using naive descriptors, and I would direct you to the reasoning above. Allowing class attributes to be reassigned is much more in line with current Python idioms.
If you really, REALLY want to make a read-only class attribute, I don't think could tell you how. But if there is a solution, it would probably involve using metaclasses and either creating a property of the metaclass or modifying the metaclass's code for setattr and delattr. But this is Deep Magic, and well beyond the scope of this answer (and my own abilities with Python).