In generale, se è necessario mantenere lo stato tra una chiamata a una funzione e l'altra, ciò che si desidera o è un oggetto (la tua soluzione) o un generatore. In alcuni casi uno sarà più semplice dell'altro, ma non c'è nulla di errato con in linea di principio (anche se sembra che tu abbia qualche problema con l'implementazione).
Il suggerimento di Sven, itertools.count()
, è un generatore. La sua attuazione è qualcosa di simile:
def count():
i = 0
while True:
yield i
i += 1
Ora, se si voleva che fosse richiamabile come una funzione, piuttosto che avere a che fare next(c)
, è possibile definire un wrapper che ha reso così:
def count(c=itertools.count()):
return next(c)
O quella linea inevitabile lambda:
count = lambda c=itertools.count(): next(c)
Poi count()
restituisce il successivo numero intero ogni volta che si chiami.
Naturalmente, se si vuole essere in grado di creare un numero illimitato di funzioni richiamabili, ciascuno con il proprio contatore, è possibile scrivere una fabbrica per questo:
def counter():
return lambda c=itertools.count(): next(c)
allora è:
c = counter()
print c() # 0
print c() # 1
# etc
Questo mi sembra ancora più semplice di un oggetto, ma non di molto. Se il tuo stato o la logica fossero più complessi, l'incapsulamento dell'oggetto potrebbe vincere.
Sei sicuro che il tuo codice funzioni? Il metodo '__get __()' viene chiamato solo quando si recupera un attributo da una classe di nuovo stile, che sembra non succedere qui. –
Sì, funziona bene. Vuoi dire che dovrebbe funzionare solo se lo faccio: 'number = new Incrementer()'? Perché? –
[Dubito che il tuo codice stampi '0 1 2'] (http://ideone.com/kvCE1). E non sto parlando di 'number = new Incrementer()' - sembra che tu stia confondendo le lingue qui, non c'è un operatore 'new' in Python. Sto parlando dell'invocazione di [descrittori] (http://docs.python.org/reference/datamodel.html#descriptors). –