Sunday, April 6, 2008

Singletons in Python - Take Two

After reading the post again I fully understand what's going on. This is a universal technique that can be implemented in the root. The downside is that a URI needs to be passed to each classes __init__ method.

I realized the stripped down version I created doesn't need the metaclass and looks like the solution I had been thinking about this past week.

WaterBlock_singleton = None

class WaterBlock(Block):
def __new__(cls, *args, **kargs):
global WaterBlock_singleton
if not WaterBlock_singleton:
obj = object.__new__(cls)
WaterBlock_singleton = obj
obj.__init__(*args, **kargs)
return WaterBlock_singleton
def __init__(self):
super(WaterBlock, self).__init__()
self.vu = BlockVu(self, 'Water Block.png')
The global is necessary because the actual class object doesn't get created until it's instantiated. If you try it inside the class definition you get this:

UnboundLocalError: local variable 'WaterBlock_singleton' referenced before assignment

This way is sort of messy, but I don't think there is a universal solution to the problem. I am not going to require passing some kind of class key inside of __init__

Therefore, I'll just run with this until a better solution comes along.

As a side note, the way I tested to see if this worked was by clicking on different Water Blocks. The selection code I wrote is universal and works on any object. I have it print the objects ID to the console as a default handler. Pretty cool.

No comments: