2016-10-18 3 views
0

Ich möchte eine Funktion haben, die Daten in eine Datei schreibt:Wie kann ich feststellen, ob ich ein dateiähnliches Objekt habe?

def data_writer(data, file_name): 
    spiffy_data = data # ... 
    with open(file_name, 'w') as out: 
     out.write(spiffy_data) 

Aber manchmal, ich habe ein Dateiobjekt anstelle eines Dateinamens. In diesem Fall habe ich manchmal eine tempfile.TemporaryFile (die ein dateiähnliches Objekt erstellt, das beschreibbar ist).

Ich möchte in der Lage sein, so etwas wie zu schreiben:

def data_writer(data, file_thing): 
    spiffy_data = data # ... 
    if type(file_thing) is file_like: 
     file_thing.write(spiffy_data) 
    else: 
     with open(file_name, 'w') as out: 
      out.write(spiffy_data) 

Was ist ein guter Weg, dies zu tun?

Macht es auch Sinn, in Python zu tun?

+1

Ich würde nur überprüfen, ob Sie eine Zeichenfolge mit 'isinstance (file_thing, str)' bekommen haben. Wenn dies der Fall ist, behandeln Sie es als Dateinamen, andernfalls behandeln Sie es als dateiähnliches Objekt. –

+3

Warum nicht immer eine Datei-Like und lassen Sie den Anrufer damit umgehen? –

+0

Alternativ dazu verwenden einige APIs ([z. B. 'tarfile.open'] (https://docs.python.org/3/library/tarfile.html#tarfile.open)) standardmäßig einen Dateinamen, erlauben aber die Weitergabe ein 'fileobj' anstatt nach Schlüsselwort, so dass es das verwendet, anstatt eine Datei zu öffnen. Bis zu dir, wenn das Sinn macht. – ShadowRanger

Antwort

0

Während Ihr Ansatz LBYL ist, ist es pythonisch anzunehmen, dass es EAFP ist. So konnte man nur try zu

  • write() zum file_thing Sie empfangen oder
  • open() es

und except eine mögliche Ausnahme, je nachdem, welche Sie sich besser fühlen den Standardfall darstellt.

Edit: Cf ShadowRanger's comment für warum das Mischen der Ausnahmebehandlung mit einem Kontextmanager ist hier eher unelegant.

+2

EAFP nicht arbeite hier so gut; zu dem Zeitpunkt, an dem Sie versuchen zu "schreiben", sind Sie bereits in der Schreiblogik und es ist peinlich, die Datei rückwirkend zu öffnen. Vor allem, wenn Sie gut sind und 'mit' Anweisungen verwenden, um die Lebensdauer eines geöffneten Dateiobjekts zu verwalten. – ShadowRanger

+0

Ja, guter Punkt. Die Handhabung der Ausnahme ist nicht gut mit dem Kontextmanager:/ – dtk

+0

Ich denke, wenn die Schreiblogik ausgeklammert wird (oder ist eigentlich ein Einzeiler), dann ist es in Ordnung. Sie müssen den Anruf kopieren/einfügen, um Daten zu schreiben, was hässlich ist, aber ich sehe dort keine Lösung ... –

3

Eine Funktion sollte eine Sache tun, und eine Sache gut machen. Im Fall von data_writer ist es eine Sache, Daten in ein dateiähnliches Objekt zu schreiben. Lassen Sie den Anrufer sich darum sorgen, ein solches Objekt zur Verfügung zu stellen. Das heißt, Sie können diesen Aufrufer auch in Form eines Wrappers bereitstellen, der einen Dateinamen annimmt und ihn für data_writer öffnet.

def data_writer(data, file_obj): 
    spiffy_data = data # ... 
    file_obj.write(spiffy_data) 

def write_data_to_file(data, file_name): 
    with open(file_name, "w") as f: 
     data_writer(f, file_name) 
Verwandte Themen