I'm trying to come up with a system for singletons, where I don't have to modify anything for an individual class except to define __metaclass__ or, if possible, to inherit another class.<div><br></div><div><div>I want it to raise an error if making a duplicate instance of a class is attempted, rather than to return the same object, because my philosophy is that if your class is a singleton and you're trying to make another instance of it then you're doing it wrong and you should probably know.  Although the way I'm trying to do it could apply to either philosophy.  </div>
<div><br></div><div>I've seen several solutions for singletons in Python, but I don't like them, either because they require modification to each individual singleton class, or they require something after the class definition like Class = Class(), or I totally don't understand them.  The novel way I've attempted to come up with is this:</div>
<div><br></div><div><div>class Singleton(type):</div><div>  def __new__(meta, classname, bases, classDict):</div><div>    @staticmethod</div><div>    def nonewinst(*args, **kwargs):</div><div>      raise ValueError("Can't make duplicate instance of singleton " + classname)</div>
<div>    @staticmethod</div><div>    def newoldnew(obj):</div><div>      return obj</div><div>    oldnew = classDict.get("__new__", newoldnew)</div><div>    @staticmethod</div><div>    def newnew(obj, *args, **kwargs):    </div>
<div>      o = oldnew(obj, *args, **kwargs) </div><div>      obj.__new__ = nonewinst</div><div>      return o</div><div>    classDict["__new__"] = newnew</div><div>    return type.__new__(meta, classname, bases, classDict)</div>
<div><br></div><div>a little bit of experimentation revealed that apparently even functions defined within a method become class methods, so i tried making them all static methods.  however, python is strange to me when it comes to methods and the self parameter.  i mean i understand a function being free of the class so that the 'self' parameter doesn't mean anything in particular unless you explicitly pass it an instance.  and i understand the method being bound to an object so that when it's called its self parameter is automatically sent the instance.  but python seems to have this in-between mode where sometimes a function isn't particularly bound to an instance but if you try to pass the wrong kind of instance to 'self' it'll complain, which gets annoying, and i don't understand how its binding works. but anyway, the problem i'm currently having with the code might not even be related to that..because here's the error I'm getting:</div>
<div><br></div><div><div>>>> from funcs import Singleton</div><div>>>> class A:</div><div>...   __metaclass__ = Singleton</div><div>...</div><div>>>> b = A()</div><div>Traceback (most recent call last):</div>
<div>  File "<stdin>", line 1, in <module></div><div>  File "c:\python25\funcs.py", line 68, in newnew</div><div>    o = oldnew(obj, *args, **kwargs)</div><div>TypeError: 'staticmethod' object is not callable</div>
<div><br></div><div>i'm not that experienced with metaclasses, but it seems to me that something's obviously going fubar here because at that point oldnew should be the function newoldnew (since class A doesn't have a __new__ defined) which is clearly defined right there with a staticmethod decorator, and first of all, functions *should* be callable, and secondly, why is my object a 'staticmethod' object just because I used a decorator on it?  it would seem it should be a function, so i tested it like this:</div>
<div><br></div><div><div>>>> class A:</div><div>...   @staticmethod</div><div>...   def b(): pass</div><div>...</div><div>>>> type(A.b)</div><div><type 'function'></div><div><br></div><div>
in that case, using @staticmethod returns a function.  i have nfi why it's different in my Singleton class.</div><div><br></div><div>oh, and thirdly, staticmethod is a decorator and decorators are callables so even given that for some mysterious reason it's a staticmethod object i don't know why it's not callable.  so that's pretty confusing.  can anyone clear this up for me?  thanks..</div>
<div><br></div></div><div>ps. i'm aware of the evils of singletons and all that.  short answer: I don't care.  :)</div><div><br></div></div></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br>
</div></div>