Em python, como verifico se um objeto é um objeto gerador?
Tentando isso -
>>> type(myobject, generator)
dá o erro -
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'generator' is not defined
(Eu sei que posso verificar se o objeto tem um next
método para ser um gerador, mas quero usar um meio para determinar o tipo de qualquer objeto, não apenas geradores.)
from types import GeneratorType;type(myobject, GeneratorType)
lhe dará o resultado adequado para objetos da classe 'gerador'. Mas, como Daenyth implica, esse não é necessariamente o caminho certo a seguir.__next__
, na verdade está aceitando qualquer iterador, não apenas geradores - o que provavelmente é o que você deseja.Respostas:
Você pode usar o GeneratorType dos tipos:
fonte
isinstance(gen, (types.GeneratorType, map, filter))
seja útil também detectarmap
efilter
. Isso ainda não inclui outros iteráveis e iteradores.Você quer dizer funções de gerador? use
inspect.isgeneratorfunction
.EDIT:
se você deseja um objeto gerador, pode usar o inspect.isgenerator, como apontado pelo JAB em seu comentário.
fonte
inspect.isgenerator
.inspect.isgenerator
é apenas uma abreviação para:isinstance(object, types.GeneratorType)
.Eu acho que é importante fazer distinção entre funções de gerador e geradores (resultado da função de gerador):
chamar a função generator_ não produzirá um resultado normal, nem executará nenhum código na própria função, o resultado será um objeto especial chamado generator :
portanto, não é função do gerador, mas gerador:
e a função de gerador não é gerador:
apenas para uma referência, a chamada real do corpo da função ocorrerá consumindo o gerador, por exemplo:
Veja também Em python, existe uma maneira de verificar se uma função é uma "função geradora" antes de chamá-la?
fonte
A
inspect.isgenerator
função está correta se você deseja procurar por geradores puros (ou seja, objetos da classe "gerador"). No entanto, ele retornaráFalse
se você marcar, por exemplo, umizip
iterável. Uma maneira alternativa de verificar um gerador generalizado é usar esta função:fonte
x=iter([1,2])
. Parece-me que está realmente testando se um objeto é ou não um iterador , não um gerador. Mas talvez "iterador" seja exatamente o que você quer dizer com "gerador generalizado".Você pode usar o iterador ou, mais especificamente, o gerador do módulo de digitação .
resultado:
fonte
typing.TypeVar
classe parecem desencorajar o usoisinstance
em conjunto com otyping
módulo: "Em tempo de execução,isinstance(x, T)
aumentaráTypeError
. Em geral,isinstance()
eissubclass()
não deve ser usado com tipos".fonte
Não faça isso. É simplesmente uma ideia muito, muito ruim.
Em vez disso, faça o seguinte:
No caso improvável de o corpo do loop for também ter
TypeError
s, existem várias opções: (1) defina uma função para limitar o escopo dos erros ou (2) use um bloco try aninhado .Ou (3) algo assim para distinguir todos esses
TypeError
s que estão flutuando.Ou (4) corrija as outras partes do seu aplicativo para fornecer geradores adequadamente. Isso geralmente é mais simples do que tudo isso.
fonte
if
declarações. E. Esse tipo de micro-otimização é uma perda de tempo. Corrija o algoritmo que produz uma mistura de iteradores e não iteradores para produzir apenas iteradores e economizar toda essa dor.Se você estiver usando o servidor da web tornado ou semelhante, pode ter descoberto que os métodos do servidor são realmente geradores e não métodos. Isso dificulta a chamada de outros métodos porque o rendimento não está funcionando dentro do método e, portanto, você precisa iniciar o gerenciamento de conjuntos de objetos do gerador em cadeia. Um método simples para gerenciar pools de geradores encadeados é criar uma função de ajuda como
Agora, escrevendo geradores encadeados, como
Produz saída
Provavelmente, é o que você deseja se estiver procurando usar geradores como uma alternativa de thread ou semelhante.
fonte
(Eu sei que é um post antigo.) Não há necessidade de importar um módulo, você pode declarar um objeto para comparação no início do programa:
fonte