È buona norma memorizzare le istanze all'interno di una variabile di classe in Python?

-1

Mi sono imbattuto in due post di Overflow dello stack che sembrano offrire risposte contrastanti:

Qualcuno può confermare se memorizzare o meno istanze di una classe all'interno di una variabile di classe della stessa classe è un pattern di progettazione Python accettabile?

    
posta atm 24.03.2017 - 17:54
fonte

2 risposte

1

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.

    
risposta data 24.03.2017 - 19:07
fonte
1

Fondamentalmente, la risposta in qualsiasi lingua a questo tipo di compromesso sarà sempre "dipende".

In Python, ottieni gli argomenti preformati dal Zen di Python .

  • Si potrebbe obiettare che rende il codice piuttosto carino e "Bello è meglio che brutto"
  • Si potrebbe sostenere che non è esplicito e che "Esplicito è meglio dell'implicito"
  • Potresti fare molti altri argomenti, facendo appello all'autorità dello Zen di Python.

Il punto non è quello di dare una risposta globalmente concreta che sarà sbagliata in alcuni casi; è limitare il modulo di argomento per indurre le persone a supportare direttamente un argomento.

Una buona discussione troverà nuove soluzioni che collegano diversi argomenti. Ad esempio, un decoratore come @singleton_list sarebbe appropriato? Si verifica un errore nel tuo dominio per inizializzare due oggetti con gli stessi parametri? In che modo è più difficile capire i consumatori di codice? Vuoi una soluzione per il tuo dominio problematico.

Dipende.

    
risposta data 24.03.2017 - 19:21
fonte

Leggi altre domande sui tag