Zanurkuj w Pythonie/Wyjątki i operacje na plikach - wszystko razem: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Piotr (dyskusja | edycje)
tłumaczenie
Sasek (dyskusja | edycje)
tłumaczenie
Linia 5:
 
'''Przykład 6.21. listDirectory'''
 
 
def listDirectory(directory, fileExtList): #(1)
"get list of file info objects for files of particular extensions"
Linia 20 ⟶ 18:
return [getFileInfoClass(f)(f) for f in fileList] #(6)
 
# <tt>listDirectory</tt> jest główną atrakcją tego modułu. Bierze ona folder <tt>directory</tt> (np. <tt class="lang-none">c:\music\_singles\</tt>) i listuje wszystkie pliki o interesujących nas rozszeżeniach (jak na przykład <tt>['.mp3']</tt>), a następnie zwraca listę instancji klas, które działają podobnie jak słowniki, a przechowują one metadane na temat każdego pliku w tym katalogu. I to wszystko jest wykonywane za pomocą kilku prostych linii kodu.
# Jak dowiedziałeś się w poprzednim rozdiale, ta linia kodu zwraca listę pełnych ścieżek wszystkich plików z folderu, które mają interesujące nas rozszerzenie (podane w argumencie <tt>fileExtList</tt>.
# As you saw in the previous section, this line of code gets a list of the full pathnames of all the files in directory that have an interesting file extension (as specified by fileExtList).
# Starzy programiści Pascala znają zagnieżdżone funkcje (funkcje wewnątrz funkcji), ale większość ludzi jest zdziwionych, gdy mówię im, że Python je wspiera. Zagniżdżona funkcja <tt>getFileInfoClass</tt> może być wywołana tylko z funkcji, w której jest zadeklarowana -- <tt>listDirectory</tt>. Jak w przypadku każdej innej funkcji. nie musisz przejmować się deklaracją interfejsu ani niczym innym. Po porstu zdefiniuj funkcję i napisz jej ciało.
# Old-school Pascal programmers may be familiar with them, but most people give me a blank stare when I tell them that Python supports nested functions -- literally, a function within a function. The nested function getFileInfoClass can be called only from the function in which it is defined, listDirectory. As with any other function, you don't need an interface declaration or anything fancy; just define the function and code it.
# NowTeraz, thatgdy you'vejuż seenznasz themoduł <tt>os module</tt>, thista linelinia shouldpowinna makenabrać more sensesensu. It gets the extensionPobiera ofona therozszerzenie filepliku (<tt>os.path.splitextsplitest(filename)[1]</tt>), forcesprzkaształca itje todo uppercasedużych liter (<tt>.upper()</tt>), slicesodcina off the dotkropkę (<tt>[1:]</tt>), andi constructstworzy anazwę classklasy nameużywając outstringu of it with string formattingformatującego. So <tt>c:\music\ap\mahadeva.mp3</tt> becomesstaje się więc <tt>.mp3</tt>, becomespotem <tt>.MP3</tt> becomesnastępnie <tt>MP3</tt> i na becomeskońcu <tt>MP3FileInfo</tt>.
# Mając nazwę klasy obsługującej ten plik, sprawdzamy czy tak klasa istnieje w tym module. Jeśli tak, zwracamy tę klasę, jeśli nie -- klasę bazową <tt>FileInfo</tt>. To bradzo ważne: zwracamy klasę. Nie obiekt, ale klasę samą w sobie.
# Having constructed the name of the handler class that would handle this file, you check to see if that handler class actually exists in this module. If it does, you return the class, otherwise you return the base class FileInfo. This is a very important point: this function returns a class. Not an instance of a class, but the class itself.
# ForDla eachkażdego filepliku inz thelisty “interesting files” list (<tt>fileList), you</tt> callwołamy <tt>getFileInfoClass</tt> withz thenazwą filenamepliku <tt>(f)</tt>. CallingWywołanie <tt>getFileInfoClass(f)</tt> returnszwraca aklasę. class;Dokłądnie younie don'twiadomo knowjaką, exactlyale which class, butto younam don'tnie careprzeszkadza. YouPotem thentworzymy createobiekt antej instanceklasy of(jaka thisona class (whateverby itnie isbyła) andi passprzekazujemy thenazwę filenamepliku (znów <tt>f again</tt>), todo thejej metody <tt>__init__ method</tt>. AsJak youpamiętasz sawz earlierwcześniejszych in this chapterrozdziałów, themetoda <tt>__init__</tt> method ofklasy FileInfo<tt>FIleInfo</tt> setsustawia <tt>self["name"]</tt>, whichco triggerspowoduje wywołanie <tt>__setitem__,</tt> whichklasy ispochodnej overridden in the descendant (<tt>MP3FileInfo)</tt> tożeby parseodpowiednio theprzetworzyć fileplik appropriatelyi towyciągnąć pulljego out the file's metadatametadane. YouRobimy do all that for eachto interestingwszystko filedla andkażdego returninteresującego apliku listi ofzwracamy thelistę resultingobiektów instanceswynikowych.
 
Zauważ, że metoda <tt>listDirectory</tt> jest bardzo ogólna. Nie wie w żaden sposób z jakimi typami plików będzie pracować ani jakie klasy są zdefiniowane do obsługi tych plików. zaczyna pracę od przejrzenia folderu, w poszukiwaniu plików do przetwarzania a potem analizuje swój moduł żeby sprawdzić, jakie klasy obsługi (jak na przykład <tt>MP3FileInfo</tt>) są zdefiniowane. Możesz rozszerzyć ten program, żeby obsługiwać inne typy plików definiując klasy o odpowiednich nazwach: <tt>HTMLFileInfo</tt> dla plikół HTML, <tt>DOCFileInfo</tt> dla plików Worda i tak dalej. <tt>listDirectory</tt> obsłuży je wszystkie bez modyfikacji, zrzucając całę przetwarzanie na odpowiednie klasy i zbierając wyniki.
Note that listDirectory is completely generic. It doesn't know ahead of time which types of files it will be getting, or which classes are defined that could potentially handle those files. It inspects the directory for the files to process, and then introspects its own module to see what special handler classes (like MP3FileInfo) are defined. You can extend this program to handle other types of files simply by defining an appropriately-named class: HTMLFileInfo for HTML files, DOCFileInfo for Word .doc files, and so forth. listDirectory will handle them all, without modification, by handing off the real work to the appropriate classes and collating the results.
 
<noinclude>