473,395 Members | 1,404 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

How does Mr. Martelli's Borg recipe work ?

I have looked long and hard at Mr. Martelli's Borg recipe:

http://aspn.activestate.com/ASPN/Coo...n/Recipe/66531

It is a very useful substitute for a Singleton, but I can't figure out
how it works. _shared_state is never assigned any value, only
self.__dict__ is assigend self._shared_sate's value - or rather
(self.)_shared_state must be assigned a value at some point, otherwise
the code wouldn't work(right ?). I have gone through the code in the
debugger several(many) times, and inserted god knows how many print
statements, but without luck(or skill i guess).

Just so you don't waste your time, i do understand that _shared_state
is a class field(variable, or what not) and that its state is shared
by all instances.

Sorry if this question is banal, but I really need to understand this,
even if it means exposing my complete lack of understanding as far as
what is probaly basic Python knowledge.

Regards,

Martin
Jul 18 '05 #1
14 2628

"Mars" <ma**************@hotmail.com> wrote in message
news:76**************************@posting.google.c om...
I have looked long and hard at Mr. Martelli's Borg recipe:

http://aspn.activestate.com/ASPN/Coo...n/Recipe/66531

It is a very useful substitute for a Singleton, but I can't figure out how it works. _shared_state is never assigned any value, only
self.__dict__ is assigend self._shared_sate's value - or rather
(self.)_shared_state must be assigned a value at some point, otherwise the code wouldn't work(right ?).


Yes and no. The 'value' of a name is the object it is assigned to.
In the last line of the 4 line code and only body line of the __init__

class Borg:
__shared_state = {}
def __init__(self):
self.__dict__ = self.__shared_state

the instance name '__dict__' is rebound to the object also called
__shared_state, so that the two names become aliases for the *same*
object (of type dict). The original instance dict gets unbound from
the name__dict__ and becomes eligible to be garbage collected. The
same is true for every Borg instance. Create 100 Borg instances and
there are 101 aliases for one and the same dict.

Now ,
instance.name = value
is (usually) executed behind the scence as
instance.__dict__['name'] = value
where __dict__ is the dict *currently* bound to instance attribute
__dict__. (One of the exceptions to this is _dict__ itself.) In the
Borg scheme, that name is no longer bound to the original dict but to
the shared dict. So nothing is (or at least need be) ever added to
that dict under its first name of __shared_state.

Terry J. Reedy
Jul 18 '05 #2
On Tue, 2003-07-22 at 20:37, Mars wrote:
I have looked long and hard at Mr. Martelli's Borg recipe:

http://aspn.activestate.com/ASPN/Coo...n/Recipe/66531

It is a very useful substitute for a Singleton, but I can't figure out
how it works.


While I don't want to discourage you from learning more about the
internals of Python objects (certainly a worthwhile goal), "singletons"
are usually thought about too hard by people new to Python. This is a
good way to make a singleton:

class _Something:
...

TheSomething = _Something()
Then just never refer to _Something again. Import TheSomething (calling
it whatever you want), and use it, not its class. It's a singleton
because there's only one of them. Simplicity!

Ian

Jul 18 '05 #3
In article <ma*********************************@python.org> , Ian Bicking
<ia**@colorstudy.com> writes

class _Something:
...

TheSomething = _Something()
Then just never refer to _Something again. Import TheSomething (calling
it whatever you want), and use it, not its class. It's a singleton
because there's only one of them. Simplicity!

Ian

.....can't one do
class TheSomething:
....

TheSomething = TheSomething()

then it's harder to get at the class which presumably is now only
available as TheSomething.__class__
--
Robin Becker
Jul 18 '05 #4
Robin Becker wrote:
....can't one do
class TheSomething:
....

TheSomething = TheSomething()

then it's harder to get at the class which presumably is now only
available as TheSomething.__class__


Well, you can name the class Hugahglaugahglaugalgha, or delete the
original class name explicitly, or any such thing. The point is that in
Python, if you're accessing a name starting with underscores in
something you don't own, you probably shouldn't be. "We're all adults
here."

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ Why place value or judgement on color?
\__/ Andrew Coler
Jul 18 '05 #5
Thanks guys - as I thought - basic stuff I had gotten wrong.

Regards,

Martin
Jul 18 '05 #6
On Wed, 2003-07-23 at 02:45, Robin Becker wrote:
....can't one do
class TheSomething:
....

TheSomething = TheSomething()

then it's harder to get at the class which presumably is now only
available as TheSomething.__class__


I wouldn't generally name the class and the singleton the same, but just
because that is confusing -- if you look briefly at the code you'll
initially think that TheSomething is a class, when it is actually an
instance. Better would be:

class _Something:
....

TheSomething = _Something()
del _Something

Ian

Jul 18 '05 #7
Quoth John Roth:
[...]
I can kind of understand the justification for the Borg pattern
in Python releases before 2.2, because there was no way of
creating a true singleton in those releases. However, in 2.2 and
later, it's really easy to create one using new style classes. [...implementing singletons with __new__...] That being the case, I'd like to see the Borg pattern go the way
of a fondly remembered hack that is no longer necessary.


Just out of curiosity: why do you prefer singletons to Borgs in
the first place?

(I don't see Borg as a hack to get the behaviour of a singleton; I
see it as a more direct way to solve the problem which singletons
are supposed to solve. Thus to me Borg is actually preferable, in
those exceedingly rare cases when that problem actually arises.)

--
Steven Taschuk st******@telusplanet.net
"I may be wrong but I'm positive." -- _Friday_, Robert A. Heinlein

Jul 18 '05 #8
On Wed, 23 Jul 2003 12:48:00 -0600, Steven Taschuk <st******@telusplanet.net> wrote:
Quoth John Roth:
[...]
I can kind of understand the justification for the Borg pattern
in Python releases before 2.2, because there was no way of
creating a true singleton in those releases. However, in 2.2 and
later, it's really easy to create one using new style classes.

[...implementing singletons with __new__...]
That being the case, I'd like to see the Borg pattern go the way
of a fondly remembered hack that is no longer necessary.


Just out of curiosity: why do you prefer singletons to Borgs in
the first place?

(I don't see Borg as a hack to get the behaviour of a singleton; I
see it as a more direct way to solve the problem which singletons
are supposed to solve. Thus to me Borg is actually preferable, in
those exceedingly rare cases when that problem actually arises.)

How about just

import zerolengthfile as borginstancename

and using it? E.g.,

[14:04] C:\pywk\clp>dir zer*, a.* b.*
<snips>
03-07-23 13:50 0 zero_len.py
03-07-23 14:01 28 a.py
03-07-23 14:02 28 b.py

[14:05] C:\pywk\clp>type a.py
import zero_len as aborg
[14:05] C:\pywk\clp>type b.py
import zero_len as bborg
[14:05] C:\pywk\clp>python
Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
import zero_len as inter
import a
import b
dir() ['__builtins__', '__doc__', '__name__', 'a', 'b', 'inter'] dir(a) ['__builtins__', '__doc__', '__file__', '__name__', 'aborg'] dir(b) ['__builtins__', '__doc__', '__file__', '__name__', 'bborg'] inter.x = 123
a.aborg.x 123 b.bborg.x 123 b.bborg.y = 456
a.aborg.y 456 inter.y 456


Regards,
Bengt Richter
Jul 18 '05 #9
Quoth Bengt Richter:
[borg vs singleton]
How about just

import zerolengthfile as borginstancename

and using it? E.g., [...]


That would be fine in many cases, I'm sure.

Modules don't do properties (or other descriptor magic), though.

--
Steven Taschuk 7\ 7'Z {&~ .
st******@telusplanet.net Y r --/hG-
(__/ )_ 1^1`

Jul 18 '05 #10
I have at times had the need to initialize some things once at the class
level, and have resorted to techniques like:

class foo:
first = True
def __init__(self):
if foo.first:
foo.first = False
# initialization code

Then a "better idea" occurred:

class foo:
def __init__(self):
del foo.__init__
# initialization code

Bob Gailer
bg*****@alum.rpi.edu
303 442 2625
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.500 / Virus Database: 298 - Release Date: 7/10/2003

Jul 18 '05 #11
On Wed, 23 Jul 2003 19:15:23 -0600, Bob Gailer wrote:
I have at times had the need to initialize some things once at the
class level


In Python 2.2 (earlier?) you can define any attribute at the class
level, and it will be shared by all instances:

class Foo( object ):
grumble = 0.1
flibble = {}
def __init__( self ):
''' Instance initialisation '''
return

This causes the attributes 'grumble', 'flibble', and '__init__()' to be
shared by all Foo instances; anything done within __init__() will affect
the individual instance only.

--
\ "I stayed up all night playing poker with tarot cards. I got a |
`\ full house and four people died." -- Steven Wright |
_o__) |
http://bignose.squidly.org/ 9CFE12B0 791A4267 887F520C B7AC2E51 BD41714B
Jul 18 '05 #12
On Wed, 23 Jul 2003 16:40:00 -0600, Steven Taschuk <st******@telusplanet.net> wrote:
Quoth Bengt Richter:
[borg vs singleton]
How about just

import zerolengthfile as borginstancename

and using it? E.g., [...]


That would be fine in many cases, I'm sure.

Modules don't do properties (or other descriptor magic), though.

Not insurmountable ;-)

====< propmod.py >==========================================
class PropModNames(object):
def __get__(self, ob, cls=None):
if ob is None: return self
return 'Shared names of propmod: %r' % vars(ob).keys()
def __set__(self, ob, val): raise AttributeError, 'names property is read-only'
def __delete__(self, ob, val): raise AttributeError, 'names property is read-only'

class SetPropModProp(object):
def __init__(self): self.name2use = None
def __get__(self, ob, cls=None):
if ob is None: return self
if not self.name2use:
props = [k for k,v in vars(ob.__class__).items()
if not k.startswith('_') and (
hasattr(v, '__get__') or hasattr(v, '__set__'))]
props.sort()
return 'Properties of propmod: %r' % props
else:
return getattr(ob.__class__, self.name2use)
def __set__(self, ob, nameNprop):
if isinstance(nameNprop,str): self.name2use = nameNprop
elif len(nameNprop)==1: delattr(ob.__class__, nameNprop[0]) # (name,) means delete
else: name, prop = nameNprop; setattr(ob.__class__, name, prop)

class PropMod(object):
names = PropModNames()
properties = SetPropModProp() # expects propmod.setprop = name, property or name2use
def __init__(self): __import__('sys').modules['propmod'] = self
================================================== ==========

===< apm.py >============
import propmod as zz
=========================

The first lines below binds the real propmod module temporarily.
The second line binds the magic propmod locally and makes it available
(by PropMod.__init__ side effect ) for import by anyone else as
an ordinary (looking) "import propmod." (Note what apm.py does).

I thought it cute to make a property that is a kind of gateway to
the class attribute space, so that one can use the .properties attribute
of the propmod module to list, store, retrieve, and delete properties -- as well
as arbitrary class variables...
import propmod
propmod = propmod.PropMod()
propmod.properties "Properties of propmod: ['names', 'properties']" propmod.names 'Shared names of propmod: []' propmod.x = 123
propmod.y = 456
propmod.names "Shared names of propmod: ['y', 'x']" propmod.properties "Properties of propmod: ['names', 'properties']" propmod.properties = ('hello', property(lambda self:'Hello properties!'))
propmod.properties "Properties of propmod: ['hello', 'names', 'properties']" propmod.hello 'Hello properties!' import apm
apm.zz.properties "Properties of propmod: ['hello', 'names', 'properties']" apm.zz.hello 'Hello properties!' apm.zz.z = 'z via apm.zz.z'
propmod.z 'z via apm.zz.z' apm.zz.names "Shared names of propmod: ['y', 'x', 'z']"

Not to go on and on, but ...
apm.zz.properties = ('hello',)
propmod.properties "Properties of propmod: ['names', 'properties']" propmod.properties = 'names'
propmod.properties <propmod.PropModNames object at 0x007E01F0> propmod.properties = ''
propmod.properties "Properties of propmod: ['names', 'properties']" propmod.properties = ('classvar', 'classvar value')
apm.zz.properties "Properties of propmod: ['names', 'properties']" apm.zz.classvar 'classvar value' apm.zz.__class__ <class 'propmod.PropMod'> apm.zz.__class__.__dict__.keys() ['__module__', 'names', '__dict__', 'classvar', '__weakref__', 'properties', '__init__', '__doc__'] apm.zz.__class__.__dict__['classvar'] 'classvar value' apm.zz.classvar = 'obj attr'
propmod.names "Shared names of propmod: ['y', 'x', 'z', 'classvar']" propmod.classvar 'obj attr' del propmod.classvar
propmod.classvar

'classvar value'

Regards,
Bengt Richter
Jul 18 '05 #13
On 24 Jul 2003 02:47:02 GMT, bo**@oz.net (Bengt Richter) wrote:
On Wed, 23 Jul 2003 16:40:00 -0600, Steven Taschuk <st******@telusplanet.net> wrote:
Quoth Bengt Richter:
[borg vs singleton]
How about just

import zerolengthfile as borginstancename

and using it? E.g., [...]
That would be fine in many cases, I'm sure.

Modules don't do properties (or other descriptor magic), though.

Not insurmountable ;-)

====< propmod.py >==========================================

[...]I thought it cute to make a property that is a kind of gateway to
the class attribute space, so that one can use the .properties attribute
of the propmod module to list, store, retrieve, and delete properties -- as well
as arbitrary class variables...


Of course,

propmod.__class__.xxx = yyy

works as well as

propmod.properties = 'xxx', yyy

so it's kind of a silly exercise, but it does demo properties for a sharable "module."

A much sparer approach:
import sys
sys.modules['simple'] = type('SimpleMod',(),{})()
import simple
simple.x = 123
simple.__class__.hi = property(lambda self:'Hi ho')
simple.x 123 simple.hi 'Hi ho' file('impsimp.py','w').write('import simple as m\n')
import impsimp
impsimp.m.hi 'Hi ho' impsimp.m.x

123

Regards,
Bengt Richter
Jul 18 '05 #14
On Wed, 2003-07-23 at 21:17, Ben Finney wrote:
On Wed, 23 Jul 2003 19:15:23 -0600, Bob Gailer wrote:
I have at times had the need to initialize some things once at the
class level


In Python 2.2 (earlier?) you can define any attribute at the class
level, and it will be shared by all instances:


This is true in all versions of Python. However, there are some
instances where you can't initialize the attributes at class creation
time, and you want to delay initializing those variables until some
later time. This usually is a problem of circular dependencies, or
where initialization somehow depends on the overall context of the
program (like configuration variables that may not be fully read by the
time the module is imported).

Ian

Jul 18 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
by: Joe Seigh | last post by:
Is there a good write on this. The textbooks I have fluff over on this? Specifically, I trying to dereference with 2 levels of type conversion not 1, i.e. X<T> -> z => Y<T> -> z => T* ->...
2
by: Nick | last post by:
Does a background fader work by... A) Changing the color after a long 'loop' statement??? B) Changing the color, then waiting a bit, then changing the color again??? To me it seems B...
1
by: Stephen Edgecombe | last post by:
Hi Environment: Visual Studio .NET 2003 (vb) I am developing an XSD Schema and want to include some building blocks from another source, so they have a different namespace. - If I use an...
1
by: David Chang | last post by:
Hi, does any one know how google analytics (urchin.js) works? I always thought javascript cannot talk to multiple servers due to security constraints. But google analytics seems to be able to...
1
parshupooja
by: parshupooja | last post by:
Hey All, I think is does work but still I wanted to make sure whether SQL Server Enterprise Edition works on Windows XP machine or not? I need to install on client worstation. thanks
1
by: =?iso-8859-1?B?S2VyZW0gR/xtcvxrY/w=?= | last post by:
Hi, can someone please tell me why the **** this does not work as expected: First at all, thats what a WMI parameter looks like: public class WMIParameter {
2
by: John Kotuby | last post by:
Hi all, I am integrating some 3rd party grids into a large ASPX form page in VS 2008 using VB. I have 4 different grids on the page. The object is to not allow the user to leave a grid if...
2
by: Brian Lowe | last post by:
I'm trying to add the content of a user control dynamically at run time, dependent upon some request attribute. My user control is a simple tell-tall so I'm sure that's not spoiling anything....
2
by: alireza6485 | last post by:
Hi, This program prints Hi and ask the user "Print again" if user types"yes" the program should priny "Hi" and ask the question again. This is the code I wrote,for some reason the program does...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.