[PEAK] 'Categories' in Python

Bob Ippolito bob at redivi.com
Fri Dec 10 18:35:15 EST 2004


On Dec 10, 2004, at 6:21 PM, Andy Gross wrote:

>
>> Your implementation is backwards.  Categories are added to existing 
>> classes without their consent.  Don't call what you're doing 
>> categories.
>
> You're right, I was reading the Objective-C specs wrong.  However, the 
> specific use case I have requires the consent of the class.  It needs 
> to define 'categories' - methods that typically operate on one two 
> data members of the class.  Can you think of a better name, or a 
> better way to think about this?

There's nothing about categories that prevent them from manipulating 
data members of the class!  Why does it require the consent of the 
class?  When you define a category, you are literally extending the 
class in such a way that it indistinguishable from if you had defined 
it on the class in the first place.

>> Also, it's not really useful to distinguish between methods that a 
>> class originally had, and the methods they acquired from a category.
>
> Maybe not enough to warrant an extra decorator, but if you wanted to 
> define rules for resolving name conflicts between category methods and 
> normal methods, it might be helpful.  Point taken, though.

Objective-C's rules are that whoever gets there last wins.  Of course, 
when most of your categories are defined statically, "last" is somewhat 
unpredictable, that is why they say the behavior is undefined.  It's 
frowned upon to override methods that are already implemented, though, 
so this conflict resolution issue never really comes up.

If you want to re-use the existing implementation of the class method, 
you can grab a reference to it before your category is created.  Any 
more "conflict resolution" than that is probably a bad idea.

>> This is an implementation of Category that works in Objective-C terms:
>
> That looks a lot nicer! (this is my first real metaclass exercise).   
> But I'd like a general facility for classes to define categories (or 
> whatever they should be called) under which they can be extended.   A 
> mechanism that could encompass both concepts with an appropriate name 
> would be ideal.  Mulling it over...

This implementation allows you to extend any class that has a writable 
dict, which is essentially "all" of them.  You can't extend built-in 
types like str or object, though, unlike other languages with this kind 
of facility.. but that is just not something you can do with the Python 
runtime without hacking C structs (we did this in Stackless, though, so 
it is possible but not recommended).

What else would you want?  Why does the class have to know or care?  I 
think this is one of those "consenting adults" things :)

BTW:  The syntax I used actually works in PyObjC 1.2 for writing 
categories on Objective-C classes from Python.

 >>> import objc
 >>> from Foundation import *
 >>> a = NSArray.arrayWithObject_('foo')
 >>> print str(a)
(foo)
 >>> class NSArray(objc.Category(NSArray)):
...     def description(self):
...         return repr(list(self))
...
 >>> print str(a)
[u'foo']

-bob




More information about the PEAK mailing list