Załóżmy, że mam plik BIG z kilkoma liniami, które chcę zignorować, oraz funkcję (file_function
), która pobiera obiekt pliku. Czy mogę zwrócić nowy obiekt pliku, którego linie spełniają pewien warunek bez czytania całego pliku najpierw, to lenistwo jest ważną częścią.Lazyly filtrowanie pliku przed odczytaniem
Uwaga: Mogę zapisać plik tymczasowy z pominięciem tych linii, ale nie jest to idealne rozwiązanie.
Na przykład, załóżmy, że miałem pliku csv (ze złej linii):
1,2
ooops
3,4
Pierwszą próbą było stworzenie nowego obiektu pliku (z tymi samymi metodami jak w pliku) i nadpisania readline
:
class FileWithoutCondition(file):
def __init__(self, f, condition):
self.f = f
self.condition = condition
def readline(self):
while True:
x = self.f.readline()
if self.condition(x):
return x
Działa, jeśli file_name
używa tylko readline
... ale nie, jeśli wymaga innej funkcjonalności.
with ('file_name', 'r') as f:
f1 = FileWithoutOoops(f, lambda x: x != 'ooops\n')
result = file_function(f1)
Roztwór stosując StringIO mogą działać, ale nie wydaje się uzyskać go.
Idealnie powinniśmy założyć, że file_function
jest funkcją blackbox, w szczególności nie mogę po prostu zmienić jej ustawień, aby zaakceptować generator (ale może uda mi się zmodyfikować generator tak, aby był podobny do pliku?).
Czy istnieje standardowy sposób wykonywania tego rodzaju leniwego (skim-) odczytu ogólnego pliku?
Uwaga: motywowanie przykładem na to pytanie jest this pandas question, gdzie tylko o readline
nie wystarczy, aby dostać pracę pd.read_csv
...
Myślę, że trzeba dokładnie wyjaśnić nam, jakie wymagania mają obiekty "plik". Jeśli potrzebuje czegoś więcej niż tylko zdolność do generowania linii, musimy wiedzieć, co jeszcze. –
@JohnZwinck Myślę, że możesz mieć rację, miałem nadzieję, że może istnieć jakiś ogólny sposób na zrobienie tego (który działałby z jakimkolwiek plikiem "może być naiwny ..." –
Być może. :) Sprawdź http: // stackoverflow.com/questions/5335017/what-is-the-minimal-subset-of-file-methods-i-need-to-implement-to-get-the-full-p, jeśli jeszcze tego nie zrobiłeś. –