Déterminer le type d'un objet?

Est-il un moyen simple de déterminer si une variable est une liste, dictionnaire, ou quelque chose d'autre? Je suis un objet qui peut être de type et j'ai besoin d'être en mesure de faire la différence.

  • Vous ne devriez pas avoir besoin de "faire la différence". Jamais. Le point de Python (et duck-typing), c'est que vous n'avez jamais besoin de savoir. Votre fonction à partir de laquelle votre "obtention d'un objet en arrière" n'est pas conçu correctement si elle retourne des objets de hasard, incompatible types.
  • Même si en général je suis d'accord avec vous, il y a des situations où il est utile de savoir. Dans ce cas particulier, il a une action rapide de piratage que j'ai finalement annulée, donc vous avez raison cette fois. Mais dans certains cas - lors de l'utilisation de la réflexion, par exemple -, il est important de savoir quel type d'objet que vous travaillez avec.
  • Vous devez fournir des exemples plus concrets de quand vous pensez que vous avez besoin de connaître le type de données. Généralement, c'est un signe de (un) une mal-fonction définie ou (b) assez pauvres polymorphisme. Il est généralement résolu avec un simple changement de conception.
  • Je serais en désaccord avec cela, en étant en mesure de connaître le type, vous pouvez faire face à certaines jolie variante d'entrée et de toujours faire la bonne chose. Il vous permet de contourner les problèmes d'interface inhérents à compter sur pur canard-typage (par exemple, l' .l'écorce() la méthode sur un Arbre signifie quelque chose de complètement différent que sur un Chien.) Par exemple, vous pourriez faire une fonction qui effectue des travaux sur un fichier qui accepte une chaîne de caractères (par exemple, un chemin d'accès), un chemin d'accès d'objet, ou une liste. Tous ont des interfaces différentes, mais le résultat final est le même: faire une opération sur le fichier.
  • P: "l' .l'écorce() la méthode sur un Arbre signifie quelque chose de complètement différent que sur un Chien". Si cela est vrai, je trouve cet exemple artificiel. Si votre demande est si désespérément confus que (1) les Chiens et les Arbres sont en train d'apparaître bon gré mal gré à l'intérieur de listes ou de n-uplets, et (2) vous avez sémantiquement surcharge d'une méthode de nom comme ça, puis la vérification de type ne va pas être de beaucoup d'aide. La "chaîne de caractères, le chemin d'accès d'objet ou une liste" exemple est aussi facilement manipulé par de simples try: blocs sans avoir recours à la vérification de type. La vérification de Type impose mauvais limites. Il étouffe "ouverte" de l'ouvert-fermé principe.
  • J'ai espéré qu'il serait évident que c'est un exemple artificiel; néanmoins, il s'agit d'une lacune importante du point de duck-typing, et qui try n'aide pas avec. Par exemple, si vous savez qu'un utilisateur pouvait passer dans une chaîne de caractères ou un tableau, les deux index sont-mesure, mais cet indice signifie quelque chose de complètement différent. Tout simplement en s'appuyant sur un try-catch dans ces cas, échoue dans l'inattendu et étrange des façons. Une solution est de faire une méthode séparée, un autre pour ajouter un peu de type de vérification. Personnellement, je préfère le comportement polymorphique sur plusieurs méthodes qui font presque la même chose...mais c'est juste moi 🙂
  • P: Ce n'est pas un "grand point d'échec", car il n'a pas vraiment d'importance. "si vous saviez qu'un utilisateur pouvait passer dans une chaîne de caractères ou un tableau," est artificiel. Vous permet de définir une API pour accepter l'un ou l'autre. Ce que l'utilisateur "pourrait passer en" n'a pas d'importance. lorsqu'ils donnent le mauvais, quelque chose de doit finit par le briser. C'est la définition de "mauvais type" -- quelque chose se brise. Ce qui conduit à une exception. Ce qui conduit à une try: la détection du mauvais type. La définition de "mauvais type" est-ce une exception doit le faux quelque part.
  • quid des tests unitaires? Parfois, vous voulez que vos tests pour vérifier qu'une fonction retourne quelque chose du bon type. Un très réel, par exemple, lorsque vous avez de la fabrique de classe.
  • Pour un peu artificiel exemple, considérons un sérialiseur/deserializer. Par définition, la conversion entre fournies par l'utilisateur des objets et une représentation sérialisée. Le sérialiseur besoins afin de déterminer le type d'objet que vous avez passé, et vous ne peut pas avoir suffisamment d'informations pour déterminer la désérialisé type sans demander l'exécution (ou à tout le moins, vous pourriez en avoir besoin pour les vérifications d'intercepter des données incorrectes avant qu'il pénètre dans votre système!)
  • Un autre scénario possible: la Capture de plusieurs types d'exceptions dans une seule "exception" bloquer, faire un peu de traitement (comme l'ajout d'info pour le message d'erreur), puis soulever l'exception avec le complément d'info. Vous pouvez "à l'Exception de (Ex1, Ex2) comme erreur:" et plus tard, lever de type(tre)(some_better_error_message). En utilisant cette méthode, on peut aussi fourre-tout sur une base type d'exception (par exemple: les demandes.des exceptions.RequestsException comme err) et puis la soulever de nouveau en utilisant le droit de sous-classe (encore une fois: lever de type(tre)(new_message)).
  • Une autre raison explicitement découvrir le type d'un objet, c'est que la documentation n'est pas toujours vous dire -- et il est parfois utile de le savoir. Donc pas de contrôle de flux, mais juste pour que vous pouvez désosser les valeurs de retour d'une fonction dans des conditions différentes. Exemple: Python3 subprocess.check_output() retourne différents types en fonction de la universal_newlines paramètre.
  • double possible de What de la manière canonique pour vérifier le type en python?
  • Aussi: Comment faire pour déterminer un Python type de la variable?