2009-06-07 12 views
9

Wystarczy spojrzeć na generatory Pythona, naprawdę pod wrażeniem ich, ale czy są jakieś rzeczy, z których nie można ich użyć? Zastanawiałem się nad przeszłym kodowaniem C, w którym czytanie z pliku lub działania użytkownika byłyby obszarami. Na przykład, czy generator może zostać użyty do zgłoszenia użytkownika do wprowadzenia (wprowadzenie danych bazowych?) I procesu wywołującego, który wprowadza? czy są jakieś problemy związane z wydajnością lub czyszczeniem?Generator Pythona - czego nie używać do

Odpowiedz

12

Jeden problem z generatorów jest to, że dostać "zużyte". Oznacza to, że jeśli chcesz powtórzyć sekwencję ponownie, musisz ponownie utworzyć generator.

Jeśli leniwy wynik jest problemem, prawdopodobnie nie chcesz generować wyrażenia. Na przykład, jeśli chcesz wykonać wszystkie swoje obliczenia z góry (na przykład, aby zwolnić zasób), najprawdopodobniej najlepiej będzie zinterpretować listę lub pętlę for.

Jeśli użyjesz psyco, uzyskasz znaczny wzrost szybkości dla wyrażeń list i pętli, ale nie dla generatorów.

Oczywiście, jeśli potrzebujesz długości sekwencji z przodu, nie chcesz generatora.

13

Generatory nie utrzymują się dobrze.

Generalnie pojawia się błąd podczas próby utrwalenia obiektu generatora.

>>> def generatorForEvenKeys(aDictionary): 
    for k in aDictionary: 
     if k % 2 == 0: yield aDictionary[k] 

>>> x = generatorForEvenKeys(someDictionary) 
>>> pickle.dump(x,file('temp.dat','wb')) 

dostaje następujący błąd:

TypeError: can't pickle generator objects 
+0

+1 dobrze wiedzieć – ebo

+0

Czy możesz podać jakiś przykład? – bayer

+0

bayer: Przykład: Iteruję nad dokumentem tekstowym i zwracam słowa. Chcę wybrać generator tak, aby móc kontynuować czytanie dokumentu tekstowego z miejsca, w którym skończyłem. Ups! Żargon. Co za PITA. –

1

użyć generatora, gdy chcemy mieć coś być iterateable, bez trzymania całą listę w pamięci (to dlatego xrange obsługuje znacznie dłuższe sekwencje niż range w Pythonie 2.x oraz niższy)

Kiedy trzeba aby załadować do pamięci całą "listę rzeczy do zrobienia", nie ma sensu używać generatora - równie dobrze możesz po prostu zwrócić listę.

Przez (nieco contrived) przykład:

def my_pointless_generator(x): 
    thedata = range(x) # or thedata = list(range(x)) in Python 3.x 
    for x in thedata: 
     yield x 

..can być zapisane tak efektywnie, jak to ..

def my_pointless_generator(x): 
    return range(x)