new-style-classes mixin

Greg Chapman glc at well.com
Fri Aug 9 02:39:11 CEST 2002


On 8 Aug 2002 04:29:14 -0700, joost_jacob at hotmail.com (J.Jacob) wrote:

>[Greg Chapman]
>> Here's an example which creates a new (mix-in) class on the
>> fly, and sets the given instance's class to it:
>> <snip> your code </snip>
>
>Thank you for your example!  Much better for new-style classes
>since it does more closely what I intended to do.  I did not
>know you could have more than 1 parameter with type(...), I did
>not find it in the 2.2.1 docs I have (searched library index).
>Where did you read about it?

Actually, I don't think it is documented, except in the (C) source.  However, it
seems to me that it should be.  The general rule is that calling the type of
something creates an instance of that something (i.e., as in PEP 253, a type is
a factory for its instances).  In this case, 'type' is the metatype of the
new-style class that doMixinNew creates, so calling 'type' (with the proper
parameters) creates a new instance of the metatype, which in this case is the
new-style class.


>
>But!
>
>It throws a TypeError when adding an old style class to an
>object of an old style class.  Maybe we have to do some trick
>that 'declares' a new style class there?  Or use assigning to
>.__bases__ in this case?
>
>It throws a TypeError when adding a new style class to an
>object of an old style class.  Probably has to do with the
>problem above.  
>
>Do you know a fix for this?  Otherwise I think I will just have
>to give up on the mixin technique for a while until I understand
>it all better and things get stable and fixed in a new Python
>version.

There's no way you can set the class of an old-style object to a new-style
class.  The class of old-style objects have to be an instance of types.ClassType
(i.e., it has to be an old-style class).  If both classes involved are old-style
classes, you can do essentially the same thing, except using new.classobj:

def doMixinOld(targetInstance, extraClass, name=''):
    instanceClass = targetInstance.__class__
    if not name:
        name = instanceClass.__name__+'_'+extraClass.__name__
    newClass = new.classobj(name, (instanceClass, extraClass), {})
    targetInstance.__class__ = newClass


>
>I feel like doing something bad when using so much __xxx__ and
>_xxx attributes.  Maybe Python needs an official builtin mixin
>function to do things like they are supposed to be done.

Well, I have to say I've never needed to use mixins on specific instances
(rather than on classes).  Looking at your demoswc.py, it seems to me it would
be more straightforward to have MyServer simply inherit from swc.Server.
Perhaps the real point is to allow any arbitrary object (from any arbitrary
module) to act as a server?  It seems like SimpleXMLRPCServer.register_instance
is designed to support this (possibly with an intermediate object to handle the
dispatching).  Is there some drawback to using that method?

---
Greg Chapman




More information about the Python-list mailing list