Le classi Python con una sola istanza: quando creare un'istanza di classe (singola) e quando invece lavorare con la classe?

6

Dato una classe Python che verrà istanziata una sola volta, cioè ci sarà solo un oggetto della classe. Mi chiedevo in quali casi avesse senso creare una singola istanza di classe invece di lavorare direttamente con la classe.

C'è un simile una-istanza , ma ha un focus diverso:

  1. si tratta del raggruppamento di variabili e funzioni globali in una classe e
  2. Non è specifico di Python. Quest'ultimo significa che non considera il fatto che le classi (in Python) siano anche oggetti.

UPDATE:

In Python, posso fare quanto segue sia con le classi sia con gli oggetti:

class A(object):
    pass

A.some_state_var = True
# Then later
A.some_state_var = False


my_a = A()

my_a.some_state_var = True
# Then later
my_a.some_state_var = False

Quindi non vedo come la scelta tra una classe e un'istanza di quella classe riguardi lo stato (in Python). Posso mantenere uno stato con uno dei due.

Inoltre, la motivazione per creare la mia istanza di classe / classe non riguarda l'applicazione di un requisito Singleton.

Inoltre, non si tratta tanto di creare un nuovo tipo.

La motivazione è raggruppare codice e dati correlati e avere un'interfaccia ad esso. Questo è il motivo per cui l'ho inizialmente modellato come una classe in un diagramma di classe. Solo quando si è arrivati all'implementazione ho iniziato a chiedermi se creare un'istanza di questa classe o meno.

    
posta stackoverflowwww 04.08.2015 - 13:24
fonte

2 risposte

12

Given a Python class which will be instantiated only once, i.e. there will be only one object of the class. I was wondering in which cases it makes sense to create a single class instance instead of working directly with the class instead.

Quindi è questo:

class Singleton:
    '''don't bother instantiating me'''
    clsvar1 = 'foo'

    @classmethod
    def foobar(cls, *args, **kwargs):
        if condition():
            cls.clsvar1 = 'bar'

contro questo?

class Singleton:
    '''instantiate and use me'''
    def __init__(self):
        self.var1 = 'foo'

    def foobar(self, *args, **kwargs):
        if condition():
            self.var1 = 'bar'

Raccomandazione

Sicuramente preferirei quello che dovrebbe essere istanziato. Quando crei un "tipo di cosa" che implica che tu crei cose di quel tipo.

The motivation is to group related code and data and having an interface to it.

Detto questo, perché non usare un modulo solo perché tutto ciò che vuoi è un namespace? I moduli sono singleton, codice relativo al gruppo e dati, e questo è un po 'più semplice e probabilmente sarebbe considerato più Pythonic:

var1 ='foo'

def foobar(*args, **kwargs):
    global var1
    if condition():
        var1 = 'bar'

Quindi l'utilizzo sarebbe al posto di:

from modules.singleton import Singleton
Singleton.foobar()

o

from modules.singleton import Singleton
the_singleton = Singleton()
the_singleton.foobar()

fai questo:

from modules import singleton
singleton.foobar()
    
risposta data 05.08.2015 - 00:48
fonte
1

I was wondering in which cases it makes sense to create a single class instance instead of working directly with the class instead.

Questa è una di quelle cose che causerà una guerra religiosa se ci entrerai molto spesso.

Ma in generale una pratica che ho visto molte volte è che i metodi di classe dovrebbero riguardare solo se stessi creando istanze di quella classe.

Se pensi a cosa sia una classe, quale sia il suo scopo / comportamento, allora ha senso. Lo scopo di una classe è creare istanze di oggetti basati su se stessi . È un progetto che può anche costruire l'edificio. Una classe "Utente" crea oggetti "utente". Una classe "Dog" crea oggetti "cane" ecc. Ecc.

Dare questo è il comportamento di una classe ha senso quindi che i metodi che aggiungi alla classe "X" si occuperanno di creare oggetti "x".

Quindi, anche se avrai sempre bisogno di un oggetto "x", dovresti comunque installarlo.

L'aggiunta di metodi alla classe X che non sono correlati alla creazione di istanze di oggetti "x" può portare a confondere codice inaspettato. Ci sono naturalmente tonnellate di esempi nel mondo reale in cui le persone lo hanno fatto comunque, ma come ho detto quella strada porta alla guerra religiosa.

    
risposta data 05.08.2015 - 10:46
fonte