2010-09-24 14 views
3

Il fut en Python (2.6) que l'on pourrait demander:Comment vérifier si un objet est une instance de 'fichier'?

isinstance(f, file) 

mais en Python 3.0 file was removed.

Quelle est la méthode appropriée pour vérifier si une variable est un fichier maintenant? Les documents ne mentionnent QUOI DE NEUF pas ...

+0

Mon Python 2.6.5 renvoie la valeur True pour isinstance (f, file), lorsque f = open ('filepath', 'r') et False pour f = ''. Je commence à penser que quelque chose d'autre pourrait être le problème ici – inspectorG4dget

+0

Les [docs actuels] (http://docs.python.org/library/functions.html#file) mentionnent en fait que l'utilisation principale de 'file' est que c'est "plus approprié \ [que' open'] de taper des tests (par exemple, écrire 'isinstance (f, fichier))' ". – intuited

+0

J'ai conclu que v3.x est cassé. – theDoctor

Répondre

5
def read_a_file(f) 
    try: 
     contents = f.read() 
    except AttributeError: 
     # f is not a file 

remplacer toutes les méthodes que vous prévoyez d'utiliser pour read. C'est optimal si vous vous attendez à ce que vous passiez un objet semblable à un fichier plus de 98% du temps. Si vous prévoyez que vous serez passé un fichier non comme objet le plus souvent 2% du temps, la bonne chose à faire est:

def read_a_file(f): 
    if hasattr(f, 'read'): 
     contents = f.read() 
    else: 
     # f is not a file 

C'est exactement ce que vous feriez si vous avez avez accès à une classe file à tester. (et FWIW, j'ai aussi file sur 2.6) Notez que ce code fonctionne aussi dans 3.x.

+0

Pas une mauvaise solution générale en l'absence de soutien plus direct dans la langue .... – theDoctor

+1

@ Mark J. Ce n'est pas une solution de contournement. Ceci est la façon correcte de traiter les tests si vous avez affaire à un fichier ou non.De cette façon, votre code fonctionne avec n'importe quel objet qui supporte l'interface minimale dont il a besoin. – aaronasterling

+1

Très bien, je vais accepter ça. Bien, je crois que c'est une verrue dans 3.0 pour ne pas être en mesure de vérifier une instance comme tous les autres types. – theDoctor

-3

Fonctionne pour moi sur python 2.6 ... Êtes-vous dans un environnement étrange où les builtins ne sont pas importés par défaut, ou où quelqu'un a fait del file, ou quelque chose?

0

En règle générale, vous n'avez pas besoin de vérifier un type d'objet, vous pouvez utiliser f.read() directement et laisser les exceptions possibles se propager - c'est soit un bug dans votre code ou un bug dans le code appelant par exemple, json.load() lève AttributeError si vous lui donnez un objet qui n'a pas d'attribut read.

Si vous devez distinguer plusieurs types d'entrée acceptables; vous pouvez utiliser hasattr/getattr:

def read(file_or_filename): 
    readfile = getattr(file_or_filename, 'read', None) 
    if readfile is not None: # got file 
     return readfile() 
    with open(file_or_filename) as file: # got filename 
     return file.read() 

Si vous souhaitez prendre en charge un cas où file_of_filename peut avoir read attribut est réglé sur None alors vous pouvez utiliser try/except plus file_or_filename.read - Note: aucun parens, l'appel ne se fait pas - - Par exemple, ElementTree._get_writer().

Si vous voulez vérifier certaines garanties, par exemple, qu'un seul appel système est fait (io.RawIOBase.read(n) pour n> 0) ou il n'y a pas de court écrit (io.BufferedIOBase.write()) ou si les méthodes de lecture/écriture acceptent des données textuelles (io.TextIOBase) puis vous pouvez utiliser la fonction isinstance() avec ABCs defined in io module par exemple, look at how saxutils._gettextwriter() is implemented.

4

Dans python3 vous pourriez se référer à io au lieu de file et écrire

import io 
isinstance(f, io.IOBase)