Bene, forse è comune farlo in Python. Tuttavia, sicuramente non è comune in altre lingue e non è un vero modo OOP. (Non voglio iniziare una guerra linguistica - au contraire, Python è un ottimo linguaggio / ambiente per alcuni casi d'uso.)
Ci sono momenti in cui assolutamente vuoi avere traccia delle istanze di una particolare classe. (Contenitori DI, risorse che non sono gestite da un garbage collector (se ne hai) ...)
Di solito è risolto implementando un modello di fabbrica. Ecco un buon articolo su Python:
link
Quando viene creata un'istanza di classe, è possibile inserire un riferimento in una raccolta. C'è un problema tecnico, tuttavia (quando si utilizzano le lingue che dispongono di garbage collector o smart pointers). Quando qualcuno interrompe l'utilizzo dell'istanza, il tuo registro ha ancora un riferimento all'istanza e quindi non è garbage collection. Devi usare un riferimento debole (o equivalente a un puntatore intelligente).
Ecco un documento Python per riferimento debole:
link
Quindi il codice potrebbe assomigliare a questo:
import weakref
shape_register = weakref.WeakValueDictionary()
class Shape(object):
# Create based on class name:
def factory(type):
#return eval(type + "()")
if type == "Circle":
instance = Circle()
shape_register[id(instance)] = instance
return instance
if type == "Square":
instance = Square()
shape_register[id(instance)] = instance
return isinstance
assert 0, "Bad shape creation: " + type
factory = staticmethod(factory)
class Circle(Shape):
def draw(self): print("Circle.draw")
def erase(self): print("Circle.erase")
class Square(Shape):
def draw(self): print("Square.draw")
def erase(self): print("Square.erase")
E l'uso:
>>> s = Shape.factory("Circle")
>>> shape_register.valuerefs()
[<weakref at 0x00000000037830F8; to 'Circle' at 0x0000000003773C18>]
^ Puoi vedere che l'istanza Circle si trova nel registro.
>>> s = Shape.factory("Circle")
>>> shape_register.valuerefs()
[<weakref at 0x0000000003759F10; to 'Circle' at 0x00000000037737F0>]
^ È stata creata una nuova istanza, non è più possibile accedere a quella originale. È stato raccolto e non viene più visualizzato nel registro.
>>> c = Shape.factory("Circle")
>>> shape_register.valuerefs()
[<weakref at 0x0000000003759F10; to 'Circle' at 0x00000000037737F0>, <weakref at 0x00000000037830F8; to 'Circle' at 0x0000000003773C18>]
>>>
^ Tuttavia ora un altro cerchio è stato creato e memorizzato in diverse variabili. Entrambe le versioni s e c sono ora accessibili e il registro mostra due valori.