2013-05-31 4 views
7

Ich bin nicht gerade neu in Python, aber ich habe immer noch Probleme zu verstehen, was etwas "Pythonic" (und das Gegenteil) macht.Warum keine len (Datei) in Python?

Also vergib mir, wenn das eine dumme Frage ist, aber warum kann ich nicht die Größe einer Datei durch eine len (Datei) bekommen?

Datei. __len__ ist nicht einmal implementiert, also ist es nicht wie es für etwas anderes benötigt wird? Wäre es aus irgendeinem Grund verwirrend/inkonsistent, wenn es implementiert wäre, um die Dateigröße zurückzugeben?

+2

(1) interaktive Interpreter 'Import this' auszuführen. (2) Um dies zu implementieren, müssten Sie die Datei bis zum Ende durchlesen. Also solltest du OS bitten, das für dich zu tun (zB wie in [dieser SO Frage]) (http://stackoverflow.com/questions/6591931/getting-file-size-in-python)) – J0HN

+0

weil jemand kam up mit os.stat und statinfo.st_size – varun

Antwort

10

Datei ist ein Iterator. Um die Anzahl der Linien zu finden Sie die gesamte Datei

sum(1 for line in file) 

lesen müssen, wenn Sie die Anzahl der Bytes in einer Datei möchten, verwenden Sie os.stat

zB

import os 
os.stat(filename).st_size 
+0

OK, die Iterator-Sache macht Sinn. Ich denke, um '__len__' für eine Datei zu implementieren, müsste sie die Datei in den Speicher lesen und dann eine len() für den Puffer machen. Wahrscheinlich keine gute Idee. So kann man das OS fragen, welches die Dateigröße bereits kennt, also os.stat. Vielen Dank! –

2

I würde sagen, da das Finden der Länge von OS-spezifischer Funktionalität abhängt. Sie können die Länge einer Datei mit diesem Code finden:

import os os.path.getsize('C:\\file.txt')

Sie auch die gesamte Datei in einen String lesen konnte und die Länge der Zeichenfolge finden. Sie möchten jedoch sicher sein, dass die Datei keine große Größe hat, die Ihren gesamten Speicher verbraucht.

2

file gibt einen Iterator zurück, so dass Sie len() nicht darauf verwenden können.

Um die Größe einer Datei erhalten Sie os.stat verwenden können:

>>> foo = os.stat("abc") 
>>> foo.st_size 
193L 

Wenn nach Größe meinen Sie Anzahl der Linien diese dann versuchen:

len(open("abc").readlines()) 

oder

sum (1 for _ in open("abc"))

+0

Eine Datei ist ein Iterator, ja, aber es gibt viele Methoden. – delnan

+0

'len (offen (" abc "). Readlines())' ist sehr elegant, danke. – PhysicalChemist

+0

Für Python 3-Lerner bedeutet "193L" nicht "193 Zeilen", sondern "193 ist eine große Zahl". – Noumenon

14

Dateien haben eine breitere Definition, besonders in Unix, als Sie vielleicht denken. Wie groß ist beispielsweise die Länge eines Druckers? Oder ein CD-ROM-Laufwerk? Beide sind Dateien in/dev und eine Art von Windows.

Für was wir normalerweise als eine Datei denken, was wäre ihre Länge? Die Größe der Variablen? Die Größe der Datei in Bytes? Letzteres macht mehr Sinn, aber dann wird es noch ekliger. Sollte die Größe des Dateiinhalts oder seine Größe auf der Festplatte aufgelistet sein (Modul-Zuordnungseinheitsgröße). Die Frage stellt sich erneut für Sparse-Dateien (Dateien, die große leere Abschnitte haben, die keinen Speicherplatz beanspruchen, aber Teil der normalerweise berichteten Größe der Datei sind, die von einigen Dateisystemen wie NTFS und XFS unterstützt wird).

Natürlich könnte die Antwort auf alle diese sein, "wählen Sie einfach eine und dokumentieren Sie, was Sie ausgewählt haben." Vielleicht sollte genau das getan werden, aber um Pythonic zu sein, muss etwas in der Regel klar sein, ohne viele Dokumente lesen zu müssen. len(string) ist meistens offensichtlich (man kann fragen, ob Bytes oder Zeichen der Rückgabewert sind), len(array) ist offensichtlich, len(file) vielleicht nicht ganz genug.

+2

Dies ist eine gute Überprüfung des Kernproblems, +1 – iruvar

+0

Beachtenswert, dass in Python 3 die starke Unterscheidung zwischen 'str' (eine Sequenz von Codepunkten) und' Bytes' (a Sequenz von Bytes) im Vergleich zu der "Unicode"/"Str" Unterscheidung in Python 2 macht es klarer, wie '__len__' für jeden definiert werden sollte. – chepner

+0

Danke, das ist eine gute Antwort. Ich habe die Lösung nur @gnibbler gegeben, weil er der erste war, der den technischen Grund wieso '__len__' für eine Datei nicht gut funktionieren würde. –

4

Also vergib mir, wenn das eine dumme Frage ist, aber warum kann ich nicht die Größe einer Datei erhalten, indem Sie eine Datei (len)?

Charles Burns' Antwort macht einen guten Punkt über Unix ist ‚Alles ist eine Datei‘ Philosophie, und obwohl man immer os.fstat() verwenden, um die zu bekommen ‚Größe‘ für jede Datei-Descriptor, mit so etwas wie ...

import os 

f = open(anything) 
size = os.fstat(f.fileno()).st_size 

... es ist nicht etwas Sinnvolles oder nützlich zurückkehren ...

>>> os.fstat(sys.stdout.fileno()).st_size 
0 
>>> fd1, fd2 = os.pipe() 
>>> os.fstat(fd1).st_size 
0 

ich denke, der Grund ist, dass ein Python-Datei-Objekt oder eine Datei-ähnliches Objekt, soll einen Strom darstellen und Ströme don haben inhärent eine Länge, besonders wenn sie schreibgeschützt sind, wie sys.stdout.

üblicherweise ist das einzige, was Sie kann Garantie über ein Python-Datei-ähnliche Objekt ist, dass es mindestens eine der read() oder write() unterstützen wird, und das ist es.

1

Eine einfache Möglichkeit, die Anzahl der Zeichen sein würde, messen:

In Python
file = open('file.bin', 'r') 
# Seek to the end. (0 bytes relative to the end) 
file.seek(0, 2) 
length = file.tell() 
Verwandte Themen