En python, comment vérifier si un objet est un objet générateur?
Essayer ça -
>>> type(myobject, generator)
donne l'erreur -
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'generator' is not defined
(Je sais que je peux vérifier si l'objet a une next
méthode pour qu'il soit un générateur, mais je veux un moyen qui me permette de déterminer le type de n'importe quel objet, pas seulement des générateurs.)
from types import GeneratorType;type(myobject, GeneratorType)
vous donnera le résultat approprié pour les objets de la classe «générateur». Mais comme Daenyth l'implique, ce n'est pas nécessairement la bonne voie à suivre.__next__
, vous acceptez en fait n'importe quel itérateur, pas seulement les générateurs - ce qui est très probablement ce que vous voulez.Réponses:
Vous pouvez utiliser GeneratorType à partir des types:
la source
isinstance(gen, (types.GeneratorType, map, filter))
- être est-il utile de détecter égalementmap
etfilter
. Cependant, cela n'inclura toujours pas les autres itérables et itérateurs.Vous voulez dire des fonctions de générateur? utiliser
inspect.isgeneratorfunction
.ÉDITER :
si vous voulez un objet générateur, vous pouvez utiliser inspect.isgenerator comme indiqué par JAB dans son commentaire.
la source
inspect.isgenerator
.inspect.isgenerator
seulement un raccourci à:isinstance(object, types.GeneratorType)
.Je pense qu'il est important de faire la distinction entre les fonctions du générateur et les générateurs (résultat de la fonction du générateur):
appeler generator_function ne donnera pas de résultat normal, il n'exécutera même pas de code dans la fonction elle-même, le résultat sera un objet spécial appelé générateur :
donc ce n'est pas une fonction de générateur, mais un générateur:
et la fonction de générateur n'est pas générateur:
juste pour une référence, l'appel réel du corps de la fonction se produira en consommant un générateur, par exemple:
Voir aussi En python, existe-t-il un moyen de vérifier si une fonction est une "fonction génératrice" avant de l'appeler?
la source
La
inspect.isgenerator
fonction est très bien si vous voulez vérifier des générateurs purs (c'est-à-dire des objets de la classe "générateur"). Cependant, il reviendraFalse
si vous cochez, par exemple, unizip
itérable. Une autre façon de rechercher un générateur généralisé est d'utiliser cette fonction:la source
x=iter([1,2])
. Il me semble que c'est vraiment de tester si un objet est un itérateur , pas un générateur. Mais peut-être que "itérateur" est exactement ce que vous entendez par "générateur généralisé".Vous pouvez utiliser l'itérateur ou plus précisément le générateur à partir du module de saisie .
résultat:
la source
typing.TypeVar
classe semble décourager l'utilisation deisinstance
en conjonction avec letyping
module: "Au moment de l'exécution,isinstance(x, T)
augmenteraTypeError
. En général,isinstance()
etissubclass()
ne doit pas être utilisé avec des types."la source
Ne fais pas ça. C'est simplement une très, très mauvaise idée.
À la place, faites ceci:
Dans le cas peu probable où le corps de la boucle for aurait également
TypeError
s, il y a plusieurs choix: (1) définir une fonction pour limiter la portée des erreurs, ou (2) utiliser un bloc try imbriqué .Ou (3) quelque chose comme ça pour distinguer tous ces
TypeError
s qui flottent.Ou (4) corrigez les autres parties de votre application pour fournir des générateurs de manière appropriée. C'est souvent plus simple que tout cela.
la source
if
déclarations. Et. Ce genre de micro-optimisation est une perte de temps. Corrigez l'algorithme qui produit un ensemble d'itérateurs et de non-itérateurs pour ne produire que des itérateurs et vous épargner toute cette douleur.Si vous utilisez le serveur Web tornado ou similaire, vous avez peut-être constaté que les méthodes serveur sont en fait des générateurs et non des méthodes. Cela rend difficile l'appel d'autres méthodes car yield ne fonctionne pas à l'intérieur de la méthode et vous devez donc commencer à gérer des pools d'objets générateurs chaînés. Une méthode simple pour gérer des pools de générateurs chaînés consiste à créer une fonction d'aide telle que
Écrivant maintenant des générateurs chaînés tels que
Produit une sortie
C'est probablement ce que vous voulez si vous cherchez à utiliser des générateurs comme alternative au thread ou similaire.
la source
(Je sais que c'est un ancien post.) Il n'est pas nécessaire d'importer un module, vous pouvez déclarer un objet pour comparaison au début du programme:
la source