[tutor] Dumb subclassing question

Andy Baker andy at andybak.net
Thu Aug 5 17:12:00 CEST 2004


> From: Kent Johnson <kent_johnson at skillsoft.com>
> Andy,
> 
> There is a way to do this by replacing path.__new__(). The 
> __new__ method of a class is a factory that returns the 
> actual instance object that will eventually be returned by 
> the call to the class itself. By replacing __new__ you can 
> return a class of a different type.
> 
> I'm not sure this is a good design. A path to a directory 
> should not have
> mp3 accessors, and an object representing an MP3 file doesn't need a
> files() method. I think Rich Krauter's approach of making an 
> MP3 class that wraps a path to a file is probably a better design.

Like I said earlier, I can see the sense in this but like you this has
become more of an abstract problem solving issue to me now!

Your idea below is some spooky voodoo! It would be way beyond my ability to
do so but your black magic could surely be wrapped in a general metaclass
type thing and given a nice syntax? On second thoughts I am sooooo running
before I can walk ;-)
 
> But you raise an interesting challenge which I couldn't 
> resist. Here is a short program that munges path() so it 
> actually returns an instance of a subclass of path:
> 
> from path import path
> 
> # Here is the new subclass
> class MyPath(path):
>      def coolStuff(self):
>          print 'It works!'
> 
> # Remember the old __new__ so we can delegate to it 
> originalNew = path.__new__
> 
> # This is going to be the new path.__new__. It will return an 
> instance of MyPath def newNew(cls, *args, **kwds):
>      return originalNew(MyPath, *args, **kwds)
> 
> # Replace path.__new__ with our new version path.__new__ = 
> staticmethod(newNew)
> 
> # Try it out
> p = path("C:")
> print type(p)
> p.coolStuff()
> 
> f = p.files()
> print f[0]
> print type(f[0])
> 
> Running this program prints
> <class '__main__.MyPath'>
> It works!
> C:.DS_Store
> <class '__main__.MyPath'>
> 
> You could change newNew so it looks at the arguments it is 
> passed and only creates a MyPath if the path has a particular 
> form, e.g. ends with '.mp3'. 
> To do this you would call originalNew(path, *args, **kwds) 
> when you want a plain path. You can read more about 
> overriding __new__ here: 
> http://www.python.org/2.2.1/descrintro.html#__new__
> 
> I hope I haven't gone beyond what is appropriate for this 
> list - this is definitely advanced stuff. But it is a good 
> chance for me to learn too!
> 
> Kent
> 



More information about the Tutor mailing list