Tengo una clase que tiene el formato singleton python estándar que uso. También tiene un único valor, pero en lugar de iniciarlo en cada instancia, lo inicio en __new__()
cuando realizo el manejo de singleton. ¿Es esta la manera pitónica de hacerlo? Si no, ¿de qué otra manera puedo?¿Es un 'pecado original' hacer trabajo de inicio en __new__? Si es así, ¿cuál es la mejor forma de manejar run once init para singletons?
class Foo(object):
_inst = None
def __new__(cls, val):
if Foo._inst is None:
Foo._inst = super(Foo, self).__new__(cls)
Foo._inst.val = val
return Foo._inst
Esta es, obviamente, la forma simplificada. He utilizado la construcción de esperar hasta __init__()
para verificar y configurar Foo._inst
para manejar ejecutar una vez init para un singleton, pero parece que está listo para errores de sincronización en una situación de multiproceso. Para situaciones donde no hay valores que puedan corromperse en la instancia existente si __init__()
se ejecuta nuevamente, no hay nada de malo en poner el init en __init__()
, excepto que está ejecutando código que efectivamente no hace nada cuando no es necesario, pero a menudo hay valores de estado corruptibles que no quiero sobrescribir. Sé que los singletons también son malos, pero a veces son la mejor solución (como definir tipos de uso especiales que deseo verificar con is
).
Esto parece ser la mejor solución que se me ocurre, pero me siento sucio al inicializar valores de instancia en __new__()
. ¿Alguien tiene ideas sobre cómo manejar esto mejor?
Es un pecado original para usar singletons. Son una forma de agregar inconvenientes adicionales y restricciones extrañas a los globales. Si necesita estado global, use globales, pero mejor intente evitarlos. Nunca use singletons. –
@Sven Marnach Hago lo que puedo para evitar singletons y globales, por supuesto, pero hay casos en que son la mejor solución. Por ejemplo, acabo de implementar una clase de Ternary, pero no necesito más de una instancia de cada tipo (True, False, Unknown), y en realidad, tener solo uno de cada uno me permite usarlo más como un bool al permitir el 'es' operador para trabajar. Por lo tanto, aunque se deben evitar los singleton, debería haber buenas maneras de usarlos cuando sean la mejor opción. –
¿No te refieres a "pecado cardinal"? –