Jak w Pythonie sprawdzić, czy obiekt jest obiektem generatora?
Próbuję tego -
>>> type(myobject, generator)
podaje błąd -
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'generator' is not defined
(Wiem, że mogę sprawdzić, czy obiekt ma next
metodę, aby był generatorem, ale chcę mieć jakiś sposób, za pomocą którego mogę określić typ dowolnego obiektu, nie tylko generatorów.)
from types import GeneratorType;type(myobject, GeneratorType)
da ci właściwy wynik dla obiektów klasy „generator”. Ale jak sugeruje Daenyth, niekoniecznie jest to właściwa droga.__next__
, w rzeczywistości akceptujesz dowolny iterator, a nie tylko generatory - co jest bardzo prawdopodobne, że chcesz.Odpowiedzi:
Możesz użyć GeneratorType z typów:
źródło
isinstance(gen, (types.GeneratorType, map, filter))
warto również wykryćmap
ifilter
. Jednak nadal nie będzie to obejmować innych iterowalnych i iteratorów.Masz na myśli funkcje generatora? używać
inspect.isgeneratorfunction
.EDYTOWAĆ :
jeśli potrzebujesz obiektu generatora, możesz użyć inspect.isgenerator, jak wskazał JAB w swoim komentarzu.
źródło
inspect.isgenerator
.inspect.isgenerator
jest tylko skrótem do:isinstance(object, types.GeneratorType)
.Myślę, że ważne jest, aby dokonać rozróżnienia między funkcjami generatorów a generatorami (wynik funkcji generatora):
wywołanie funkcji generator_function nie przyniesie normalnego wyniku, nawet nie wykona żadnego kodu w samej funkcji, wynikiem będzie specjalny obiekt o nazwie generator :
więc nie jest to funkcja generatora, ale generator:
a funkcja generatora nie jest generatorem:
tylko w celach informacyjnych, faktyczne wywołanie treści funkcji nastąpi poprzez zużycie generatora, np .:
Zobacz także Czy w pythonie istnieje sposób sprawdzenia, czy funkcja jest „funkcją generatora” przed jej wywołaniem?
źródło
inspect.isgenerator
Funkcja jest w porządku, jeśli chcesz sprawdzić czystych generatorów (czyli obiektów „generator” klasa). Jednak zwróci,False
jeśliizip
zaznaczysz na przykład iterowalny plik . Alternatywnym sposobem sprawdzenia generatora uogólnionego jest użycie tej funkcji:źródło
x=iter([1,2])
. Wydaje mi się, że to naprawdę sprawdza, czy obiekt jest iteratorem , a nie generatorem. Ale może „iterator” jest dokładnie tym, co masz na myśli, mówiąc o „generatorze uogólnionym”.Możesz użyć Iteratora lub dokładniej Generatora z modułu pisania .
wynik:
źródło
typing.TypeVar
klasy wydaje się zniechęcać do używaniaisinstance
w połączeniu ztyping
modułem: „W czasie wykonywaniaisinstance(x, T)
spowoduje podniesienieTypeError
. Ogólnieisinstance()
iissubclass()
nie powinno się ich używać z typami”.źródło
Nie rób tego. To po prostu bardzo, bardzo zły pomysł.
Zamiast tego zrób to:
W mało prawdopodobnym przypadku, gdy treść pętli for również ma
TypeError
s, istnieje kilka możliwości: (1) zdefiniowanie funkcji ograniczającej zakres błędów lub (2) użycie zagnieżdżonego bloku try .Lub (3) coś takiego, aby rozróżnić wszystkie te
TypeError
pływające wokół.Lub (4) napraw inne części aplikacji, aby odpowiednio zapewnić generatory. To często prostsze niż to wszystko.
źródło
if
instrukcje. I. Taka mikro-optymalizacja to strata czasu. Napraw algorytm, który tworzy mieszany zestaw iteratorów i nie-iteratorów, aby wytwarzać tylko iteratory i oszczędzić sobie całego tego bólu.Jeśli używasz serwera WWW tornado lub podobnego, być może zauważyłeś, że metody serwera są w rzeczywistości generatorami, a nie metodami. Utrudnia to wywoływanie innych metod, ponieważ yield nie działa wewnątrz metody i dlatego musisz zacząć zarządzać pulami połączonych obiektów generatora. Prostą metodą zarządzania pulami połączonych generatorów jest utworzenie funkcji pomocy, takiej jak
Teraz piszemy generatory łańcuchowe, takie jak
Produkuje wynik
Co prawdopodobnie jest tym, czego chcesz, jeśli chcesz używać generatorów jako alternatywy dla wątku lub podobnej.
źródło
(Wiem, że to stary post.) Nie ma potrzeby importowania modułu, możesz zadeklarować obiekt do porównania na początku programu:
źródło