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?
André 10 1466
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 Haese http://informixdb.sourceforge.net
On Sep 7, 10:27 am, Carsten Haese <cars...@uniqsys.comwrote:
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'
André wrote:
On Sep 7, 10:27 am, Carsten Haese <cars...@uniqsys.comwrote:
>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:
1. It stops the super-class's __init__() method from being called, and
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.
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 -------------
On Fri, 2007-09-07 at 15:54 +0000, André wrote:
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 [...]
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'
Indeed, if you have an __init__ method that shouldn't see the "group"
argument, you need a metaclass after all so you can yank the "group"
argument between __new__ and __init__. The following code seems to work,
but it's making my brain hurt:
class SplinterBorgMeta(type):
def __call__(cls, *args, **kwargs):
inst = cls.__new__(cls, *args, **kwargs)
kwargs.pop("group",None)
inst.__init__(*args,**kwargs)
return inst
class SplinterBorg(object):
__metaclass__ = SplinterBorgMeta
_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
The alternatives, as Steve just pointed out, would be not to subclass
SplinterBorg or to provide an __init__ method that expects a "group"
argument.
HTH,
--
Carsten Haese http://informixdb.sourceforge.net
On Sep 7, 3:53 pm, Steve Holden <st...@holdenweb.comwrote:
André wrote:
On Sep 7, 10:27 am, Carsten Haese <cars...@uniqsys.comwrote:
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 -------------
On Sep 7, 4:00 pm, Carsten Haese <cars...@uniqsys.comwrote:
On Fri, 2007-09-07 at 15:54 +0000, André wrote:
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
[...]
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'
Indeed, if you have an __init__ method that shouldn't see the "group"
argument, you need a metaclass after all so you can yank the "group"
argument between __new__ and __init__. The following code seems to work,
but it's making my brain hurt:
class SplinterBorgMeta(type):
def __call__(cls, *args, **kwargs):
inst = cls.__new__(cls, *args, **kwargs)
kwargs.pop("group",None)
inst.__init__(*args,**kwargs)
return inst
class SplinterBorg(object):
__metaclass__ = SplinterBorgMeta
_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
The alternatives, as Steve just pointed out, would be not to subclass
SplinterBorg or to provide an __init__ method that expects a "group"
argument.
HTH,
Thanks for your reply. I will try to adapt it and see if it works in
my case.
André
--
Carsten Haesehttp://informixdb.sourceforge.net
Carsten Haese wrote:
Indeed, if you have an __init__ method that shouldn't see the "group"
argument, you need a metaclass after all so you can yank the "group"
argument between __new__ and __init__. The following code seems to work,
but it's making my brain hurt:
class SplinterBorgMeta(type):
def __call__(cls, *args, **kwargs):
inst = cls.__new__(cls, *args, **kwargs)
kwargs.pop("group",None)
inst.__init__(*args,**kwargs)
return inst
class SplinterBorg(object):
__metaclass__ = SplinterBorgMeta
_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
I think I would probably write that as::
>>class SplinterBorgMeta(type):
... def __init__(cls, name, bases, bodydict):
... cls._shared_states = {}
... def __call__(cls, *args, **kwargs):
... group = kwargs.pop('group', None)
... inst = cls.__new__(cls, *args, **kwargs)
... inst.__dict__ = cls._shared_states.setdefault(group, {})
... inst.__init__(*args, **kwargs)
... return inst
...
>>class MyClass(object):
... __metaclass__ = SplinterBorgMeta
... def __init__(self, name):
... self.name = name
...
>>a = MyClass('a') aa = MyClass('aa') b = MyClass('b', group='b') bb = MyClass('bb', group='b') a.name, aa.name, b.name, bb.name
('aa', 'aa', 'bb', 'bb')
That is, I don't think there's really a need for __new__ if you're using
a metaclass. Just set the instance's __dict__ in the __call__ method of
the metaclass.
STeVe
On Fri, 2007-09-07 at 14:54 -0600, Steven Bethard wrote:
Carsten Haese wrote:
[slightly convoluted example...]
I think I would probably write that as::
[concise example...]
That is, I don't think there's really a need for __new__ if you're using
a metaclass. Just set the instance's __dict__ in the __call__ method of
the metaclass.
Good point. I suppose it shows that this is the first metaclass I've
ever written, but it works, and it didn't make my brain explode ;)
--
Carsten Haese http://informixdb.sourceforge.net
On Sep 7, 1:53 pm, Steve Holden <st...@holdenweb.comwrote:
All you really need is to create your SplinterBorgs with appropriate
group names, you don't neef subclasses at all:
Dang. With that subject heading I thought this was about some post-
Singularity, Python-programmed cyborgs rising up to take over the
universe.
See, e.g.
<a href="http://www.amazon.com/How-Survive-Robot-Uprising-Defending/dp/
1582345929/inscape-20">How To Survive A Robot Uprising</a>
I am officially misled!
rd
On Sep 7, 1:53 pm, Steve Holden <st...@holdenweb.comwrote:
All you really need is to create your SplinterBorgs with appropriate
group names, you don't neef subclasses at all:
oops, I tried this once and the link broke. I'll try tinyurl.
Dang. With that subject heading I thought this was about some post-
Singularity, Python-programmed cyborgs rising up to take over the
universe.
See, e.g.
How To Survive A Robot Uprising http://tinyurl.com/yrk5pw
I am officially misled!
rd This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Irmen de Jong |
last post by:
Hi,
I've developed the Metaclass below, because I needed a way
to make a bunch of classes thread-safe.
I didn't want to change every method of the class by adding
lock.aqcuire()..lock.release()...
|
by: Jacek Generowicz |
last post by:
I would like to write a metaclass which would allow me to overload
names in the definition of its instances, like this
class Foo(object):
__metaclass__ = OverloadingClass
att = 1
att = 3
|
by: Steven D'Aprano |
last post by:
I've been working with the Borg design pattern from here:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531
and I'm having problems subclassing it.
I'm a newbie, so I've probably...
|
by: Pedro Werneck |
last post by:
Hi
I have a class A, with metaclass M_A, and class B, subclass of A, with
metaclass M_B, subclass of M_A.
A class C, subclass of B must have M_B or a subclass of it as metaclass,
but what if...
|
by: mikelostcause |
last post by:
Is there anyway to hold the base.WndProc(ref m) until after the Logout()
function finishes loading a webpage??
I'm working on shutting down an app that runs in the system tray, I have no...
|
by: Jake Barnes |
last post by:
I searched comp.lang.javascript on Google Groups but I didn't find an
answer when I searched for "viewport" or "viewport div" or any
combination of words using "viewport" so now I think I'm...
|
by: Chuck B |
last post by:
I have a .NET application installed on a server. It runs fine when I run an
instance on my PC. My question is, is it possible to run a .NET app hosted
on a server without having the framework...
|
by: Chuck B |
last post by:
Is it equally possible to create WPF objects for use in a web browser as
well as WinForms?
|
by: Lie |
last post by:
This is probably unrelated to Python, as this is more about design
pattern. I'm asking your comments about this design pattern that is
similar in functionality to Singleton and Borg: to share...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM)
The start time is equivalent to 19:00 (7PM) in Central...
|
by: erikbower65 |
last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps:
1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal.
2. Connect to...
|
by: erikbower65 |
last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA:
1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
|
by: kcodez |
last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
|
by: Taofi |
last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same
This are my field names
ID, Budgeted, Actual, Status and Differences
...
|
by: DJRhino1175 |
last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this -
If...
|
by: Rina0 |
last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
|
by: DJRhino |
last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer)
If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _
310030356 Or 310030359 Or 310030362 Or...
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
| |