madpython <[EMAIL PROTECTED]> wrote: > For the pure theory sake and mind expansion i got a question. > Experimenting with __new__ i found out how to create a singleton. > class SingleStr(object): > def __new__(cls,*args,**kwargs): > instance=cls.__dict__.get('instance') > if instance: > return instance > cls.instance=object.__new__(cls,*args,**kwargs) > return cls.instance > > What if i need to create no more than 5 (for example) instances of a
And what if somebody asks for a 6th one -- raise an exception? or return a random one of the 5? Ah well, anyway...: > class. I guess that would be not much of a problema but there is a > complication. If one of the instances is garbagecollected I want to be > able to spawn another instance. Maybe it's difficult to perceive what i > said so think of a limited number of sockets. Wherenever one is freed > it can be captured again. Have the class hold weak references to the instances. E.g.: import weakref import random class JustFive(object): _counter = 0 _insts = weakref.WeakKeyDictionary() def __new__(cls): if len(cls._insts) < 5: inst = object.__new__(cls) inst.id = cls._counter cls._insts[inst] = None cls._counter += 1 else: inst = random.choice(cls._insts.keys()) return inst Testing this for the specified behavior should be done more systematically, of course, but here's a snippet based only on showing exactly what's going on...: if __name__ == '__main__': samp = [JustFive() for i in range(7)] def showsamp(): for s in samp: print s.id, ss = set(s.id for s in samp) print '{', for s in sorted(ss): print '%d,'%s, print '} #%d'%len(ss) print 'Start with:', showsamp() for x in range(10): i = random.randrange(len(samp)) print ('@%d,'%i), samp[i].id, '->', samp[i] = None newone = JustFive() samp[i] = newone print '%d,' % samp[i].id, showsamp() A sample run might go, for example...: Start with: 0 1 2 3 4 4 1 { 0, 1, 2, 3, 4, } #5 @0, 0 -> 5, 5 1 2 3 4 4 1 { 1, 2, 3, 4, 5, } #5 @1, 1 -> 3, 5 3 2 3 4 4 1 { 1, 2, 3, 4, 5, } #5 @6, 1 -> 6, 5 3 2 3 4 4 6 { 2, 3, 4, 5, 6, } #5 @2, 2 -> 7, 5 3 7 3 4 4 6 { 3, 4, 5, 6, 7, } #5 @4, 4 -> 7, 5 3 7 3 7 4 6 { 3, 4, 5, 6, 7, } #5 @4, 7 -> 6, 5 3 7 3 6 4 6 { 3, 4, 5, 6, 7, } #5 @1, 3 -> 7, 5 7 7 3 6 4 6 { 3, 4, 5, 6, 7, } #5 @3, 3 -> 8, 5 7 7 8 6 4 6 { 4, 5, 6, 7, 8, } #5 @6, 6 -> 5, 5 7 7 8 6 4 5 { 4, 5, 6, 7, 8, } #5 @2, 7 -> 6, 5 7 6 8 6 4 5 { 4, 5, 6, 7, 8, } #5 and the point is that the sample always has a set of objects with exactly 5 separate id values, but the set "migrates" upwards as some objects happen to be dropped. Well, not always "upwards" as smoothly as luck would have it in this case, e.g., another run goes: Start with: 0 1 2 3 4 1 2 { 0, 1, 2, 3, 4, } #5 @1, 1 -> 3, 0 3 2 3 4 1 2 { 0, 1, 2, 3, 4, } #5 @2, 2 -> 4, 0 3 4 3 4 1 2 { 0, 1, 2, 3, 4, } #5 @3, 3 -> 1, 0 3 4 1 4 1 2 { 0, 1, 2, 3, 4, } #5 @1, 3 -> 5, 0 5 4 1 4 1 2 { 0, 1, 2, 4, 5, } #5 @5, 1 -> 5, 0 5 4 1 4 5 2 { 0, 1, 2, 4, 5, } #5 @6, 2 -> 6, 0 5 4 1 4 5 6 { 0, 1, 4, 5, 6, } #5 @2, 4 -> 1, 0 5 1 1 4 5 6 { 0, 1, 4, 5, 6, } #5 @4, 4 -> 7, 0 5 1 1 7 5 6 { 0, 1, 5, 6, 7, } #5 @6, 6 -> 8, 0 5 1 1 7 5 8 { 0, 1, 5, 7, 8, } #5 @3, 1 -> 8, 0 5 1 8 7 5 8 { 0, 1, 5, 7, 8, } #5 here, the objects with ids 0 and 1 just never happen to get dropped. Alex -- http://mail.python.org/mailman/listinfo/python-list