Need help subclassing Borg

Jeremy Bowers jerf at jerf.org
Sat May 7 10:29:16 EDT 2005


On Sun, 08 May 2005 02:42:09 +1000, Steven D'Aprano wrote:
> I'm thinking what I might need is a function that generates a Borg-like
> class. So I would do something like:
> 
> Rabbit = MakeBorgClass()
> # Rabbit is now a class implementing shared state
> # all instances of Rabbit share the same state
> Duck = MakeBorgClass()
> # Duck is now a class implementing shared state
> # all instances of Duck share the same state
> # but instances of Duck do not share state with instances of Rabbit
> 
> Problem is, I haven't got the foggiest idea how to implement something
> like that. Am I on the right track? Where do I go from here?

Bengt's answer is better than this track, but this question is worth
answering because it is so wonderfully easy in Python.

Remember class is an executable statement, not a declaration:

Python 2.3.5 (#1, Mar  3 2005, 17:32:12) 
[GCC 3.4.3  (Gentoo Linux 3.4.3, ssp-3.4.3-0, pie-8.7.6.6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def makeBorg():
...     class Borg(object):
...             _shared_state = {}
...             def __init__(self):
...                     self.__dict__ = self._shared_state
...     return Borg
... 
>>> Duck = makeBorg()
>>> Rabbit = makeBorg()
>>> d = Duck()
>>> d2 = Duck()
>>> d.cover = "fur"
>>> d2.cover
'fur'
>>> r = Rabbit()
>>> r.cover
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'Borg' object has no attribute 'cover'
>>> r.cover = "feathers"
>>> d.cover
'fur'
>>> r2 = Rabbit()
>>> r2.cover
'feathers'
>>> 

(I flipped around the fur and feathers, but don't feel like fixing it :-) )

Now, the problem with this and the reason why Bengt's is more likely
better is that each of these Borg classes is unrelated, so there's no
using issubclass or anything like that. You *could* hack around this, but
it's not worth it. (It is possible to dynamically choose the bases of a
class; you can't do it in the class statement itself, but you can do
something like:

def makeBorg(base = object):
	class Borg(base): 
		etc.

but this is definitely not the best way to go. Still, as above, it does
have its place other times; I've used it to dynamically pick up whether
the user has certain modules installed and add support depending on the
environment. I often do this when I'm writing something currently embedded
in an app I'm writing, but may have use elsewhere outside of the
environment of the app, allowing me to write code that both takes full
advantage of the app environment, while not being completely tied to it.)



More information about the Python-list mailing list