Changing the state of another entity into the constructor method I have a Clock class who inherites from pyglet.clock.Clock and behaves like a Singleton.

Into the constructor method I have the following line:

pyglet.clock.set_default(self)


Who changes the state of the default clock of pyglet, setting my Clock object as the default clock.

The constructor method leaves the Clock object into a valid state (without this line in the constructor the clock don't tick!).

Changing another entity state in the constructor:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pyglet

import singleton

class Clock(pyglet.clock.Clock):
    __metaclass__ = singleton.Singleton

    def __init__(self):
        super(Clock, self).__init__()

        pyglet.clock.set_default(self)

class Test(object):
    def update(self, dt):
        print dt

w = pyglet.window.Window()
@w.event
def on_draw():
    w.clear()

t = Test()

c = Clock()
c.schedule_interval(t.update, 1/60.0)

pyglet.app.run()


On the other hand I can do:

Calling pyglet.clock.set_default outside of the constructor:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pyglet

import singleton

class Clock(pyglet.clock.Clock):
    __metaclass__ = singleton.Singleton

    def __init__(self):
        super(Clock, self).__init__()

class Test(object):
    def update(self, dt):
        print dt

w = pyglet.window.Window()
@w.event
def on_draw():
    w.clear()

t = Test()

c = Clock()
pyglet.clock.set_default(self)
c.schedule_interval(t.update, 1/60.0)

pyglet.app.run()


In this case the call:

pyglet.clock.set_default(self)


Is outside of the constructor method and then the constructor method don't change the state of another entity.

The questions:


What is the solution more elegant or pythonic?
Is any of these solutions a best practice?
How do you resolve this issue?
In Python, a singleton should be a module, not a class. There's no good reason to define a class for that. That's what's going on in pyglet's case with pyglet.clock. If you want to define your own version you should do something like:

# myclock.py

from pyglet.clock import *


Then you can add functions/etc to that module to get additional behavior. This way you don't even need to call the set_default function.