On Sep 7, 3:53 pm, Steve Holden <[EMAIL PROTECTED]> wrote: > André wrote: > > On Sep 7, 10:27 am, Carsten Haese <[EMAIL PROTECTED]> wrote: > >> On Fri, 2007-09-07 at 12:31 +0000, André wrote: > >>> In my application, I make use of the Borg idiom, invented by Alex > >>> Martelli. > >>> class Borg(object): > >>> '''Borg Idiom, from the Python Cookbook, 2nd Edition, p:273 > >>> Derive a class form this; all instances of that class will share > >>> the > >>> same state, provided that they don't override __new__; otherwise, > >>> remember to use Borg.__new__ within the overriden class. > >>> ''' > >>> _shared_state = {} > >>> def __new__(cls, *a, **k): > >>> obj = object.__new__(cls, *a, **k) > >>> obj.__dict__ = cls._shared_state > >>> return obj > >>> ---- > >>> This has worked very well so far, but is starting to impose some > >>> unwanted constraints on my program design. > >>> What I would like to do is, to put it figuratively, create a Borg > >>> rebellion with various splinter groups. In concrete Python terms, I > >>> would like to have > >>> class MyClass(Borg, ...): > >>> ... > >>> seven_of_nine = MyClass(...) # part of group "BORG" > >>> two_of_nine = MyClass(...) > >>> splinter1 = MyClass(..., group='splinter') > >>> splinter2 = MyClass(..., group='splinter') > >>> and have splinter 1 and splinter2 share the same state, but a > >>> different state than the one shared by members of the BORG collective. > >>> Any suggestions from the metaclass experts? > >> You don't need a metaclass. Just turn _shared_state into a dictionary of > >> shared states, keyed by the group name: > > >> class SplinterBorg(object): > >> _shared_states = {} > >> def __new__(cls, *a, **k): > >> group = k.pop("group","BORG") > >> obj = object.__new__(cls, *a, **k) > >> obj.__dict__ = cls._shared_states.setdefault(group,{}) > >> return obj > > >> HTH, > > >> -- > >> Carsten Haesehttp://informixdb.sourceforge.net > > > Unfortunately, it fails. Here's what I tried, followed by the > > traceback > > class SplinterBorg(object): > > _shared_states = {} > > def __new__(cls, *a, **k): > > group = k.pop("group","BORG") > > obj = object.__new__(cls, *a, **k) > > obj.__dict__ = cls._shared_states.setdefault(group,{}) > > return obj > > > class MyClass(SplinterBorg): > > def __init__(self, name): > > self.name = name > > > a1 = MyClass('a') > > a2 = MyClass('aa') > > b1 = MyClass('b', group="B") > > > Traceback (most recent call last): > > File "test.py", line 15, in <module> > > b1 = MyClass('b', group="B") > > TypeError: __init__() got an unexpected keyword argument 'group' > > Because your subclass signature is completely wrong. Why did you feel > you had to add an __init__() method to your subclass? This has two bvad > effects:
Because this is what I need to do currently with using the standard Borg class, and is something I would like to be able to do. Here's a simplified version of the current usage I have ===== class Borg(object): _shared_state = {} def __new__(cls, *a, **k): obj = object.__new__(cls, *a, **k) obj.__dict__ = cls._shared_state return obj class BorgConsole(Borg, SingleConsole): '''Every BorgConsole share a common state''' def __init__(self, locals={}, filename="Crunchy console"): SingleConsole.__init__(self, locals, filename=filename) ===== and it is called via something like a_console = BorgConsole(locals) where locals is a previously defined dict. Note that a number of such instances are created dynamically as the program is used. What I would like to do is to be able to add a "page_id" (the Borg group referred to my previous message), so that I could call a_console = BorgConsole(locals, page_id) where page_id would be an optional argument, defaulting to the BORG group, as mentioned in my original post. I must admit I did not try with keywords arguments ... and will not be for a couple of hours while I am at work. > > 1. It stops the super-class's __init__() method from being called, and > I don't understand why this is so here, and not with the usual Borg case as I used it... > 2. It breaks the calling syntax specified in the superclass. > > All you really need is to create your SplinterBorgs with appropriate > group names, you don't neef subclasses at all: > > a1 = SplinterBorg(group="one") > a2 = SplinterBorg(group="two") > > and so on. > > If you want to create subclasses then they should work like this: > > class MyBorg1(SplinterBorg): > def __init__(self): > SplinterBorg.__init__(self, group='borg1') > > and so on, with a different group for each. But this seems over complicated. > I do need subclasses (I think) as my classes inherit from more than the SplinterBorg class... I'll see what I can do following some of your suggestions. Thanks for the reply, André > regards > Steve > -- > Steve Holden +1 571 484 6266 +1 800 494 3119 > Holden Web LLC/Ltd http://www.holdenweb.com > Skype: holdenweb http://del.icio.us/steve.holden > --------------- Asciimercial ------------------ > Get on the web: Blog, lens and tag the Internet > Many services currently offer free registration > ----------- Thank You for Reading ------------- -- http://mail.python.org/mailman/listinfo/python-list