¿Cómo puedo memorizar una instanciación de clase en Python?

Ok, aquí está el escenario del mundo real: estoy escribiendo una aplicación, y tengo una clase que representa un cierto tipo de archivos (en mi caso, esto es fotografías pero ese detalle es irrelevante para el problema). Cada instancia de la clase de fotografía debe ser única para el nombre de archivo de la foto.

El problema es que cuando un usuario le dice a mi aplicación que cargue un archivo, debo poder identificar cuándo ya están cargados los archivos y usar la instancia existente para ese nombre de archivo, en lugar de crear instancias duplicadas en el mismo nombre de archivo.

Para mí, esta es una buena situación para usar la memorización, y hay muchos ejemplos de eso, pero en este caso no solo estoy memorizando una función ordinaria, necesito estar memorizando__init__(). Esto plantea un problema, porque por el momento__init__() se llama ya es demasiado tarde porque ya se ha creado una nueva instancia.

En mi investigación encontré Python__new__() Método, y en realidad pude escribir un ejemplo trivial de trabajo, pero se derrumbó cuando intenté usarlo en mis objetos del mundo real, y no estoy seguro de por qué (lo único que puedo pensar es que mi verdadero los objetos del mundo eran subclases de otros objetos que realmente no puedo controlar, por lo que hubo algunas incompatibilidades con este enfoque). Esto es lo que yo tenía:

class Flub(object):
    instances = {}

    def __new__(cls, flubid):
        try:
            self = Flub.instances[flubid]
        except KeyError:
            self = Flub.instances[flubid] = super(Flub, cls).__new__(cls)
            print 'making a new one!'
            self.flubid = flubid
        print id(self)
        return self

    @staticmethod
    def destroy_all():
        for flub in Flub.instances.values():
            print 'killing', flub


a = Flub('foo')
b = Flub('foo')
c = Flub('bar')

print a
print b
print c
print a is b, b is c

Flub.destroy_all()

Que la salida de este:

making a new one!
139958663753808
139958663753808
making a new one!
139958663753872
<__main__.Flub object at 0x7f4aaa6fb050>
<__main__.Flub object at 0x7f4aaa6fb050>
<__main__.Flub object at 0x7f4aaa6fb090>
True False
killing <__main__.Flub object at 0x7f4aaa6fb050>
killing <__main__.Flub object at 0x7f4aaa6fb090>

¡Es perfecto! Solo se hicieron dos instancias para los dos identificadores únicos dados, y las instancias de Flub claramente solo tienen dos enumeradas.

Pero cuando intenté adoptar este enfoque con los objetos que estaba usando, recibí todo tipo de errores sin sentido acerca de cómo__init__() Tomé solo 0 argumentos, no 2. Así que cambiaría algunas cosas y luego me diría que__init__() Necesitaba un argumento. Totalmente extraño.

Después de un tiempo de luchar con él, básicamente me di por vencido y moví todos los__new__() La magia negra en un método estático llamadoget, tal que yo podría llamarPhotograph.get(filename) y solo llamaríaPhotograph(filename) si el nombre del archivo no estaba ya enPhotograph.instances.

¿Alguien sabe dónde me equivoqué aquí? ¿Hay alguna manera mejor de hacer esto?

Otra forma de verlo es que es similar a un singleton, excepto que no es globalmente singleton, solo singleton por nombre de archivo.

Aquí está mi código del mundo real utilizando el método static get Si quieres verlo todo junto.

Respuestas a la pregunta(3)

Su respuesta a la pregunta