| You are here: Inicio > Inmersión en Python > Excepciones y gestión de ficheros > Todo junto | << >> | ||||
Inmersión en PythonPython de novato a experto |
|||||
Una vez más, todas las piezas de dominó están en su lugar. Ha visto cómo funciona cada línea de código. Ahora retrocedamos y veamos cómo encaja todo.
def listDirectory(directory, fileExtList):"""obtener lista de objetos de información sobre ficheros de extensiones particulares""" fileList = [os.path.normcase(f) for f in os.listdir(directory)] fileList = [os.path.join(directory, f) for f in fileList if os.path.splitext(f)[1] in fileExtList]
def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]):
"obtener la clase de información de un fichero por su extensión" subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:]
return hasattr(module, subclass) and getattr(module, subclass) or FileInfo
return [getFileInfoClass(f)(f) for f in fileList]
| listDirectory es la atracción principal de todo este módulo. Toma un directorio (como c:\music\_singles\ en mi caso) y una lista de extensiones de fichero interesantes (como ['.mp3']), y devuelve una lista de instancias de clases que actúan como diccionarios que contienen metadatos sobre cada fichero interesante de ese directorio. Y lo hace en unas pocas líneas de código bastante simples. | |
| Como pudo ver en la sección anterior, esta línea de código devuelve una lista de las rutas absolutas de todos los ficheros de directory que tienen una extensión interesante (especificada por fileExtList). | |
| Los programadores de Pascal de la vieja escuela estarán familiarizados con ellas, pero la mayoría de la gente se me queda mirando con cara de tonto cuando digo que Python admite funciones anidadas (literalmente, una función dentro de otra). Sólo se puede llamar a la función anidada getFileInfoClass desde dentro de la función en que está definida, listDirectory. Como con cualquier otra función, no necesita una interfaz de declaración ni nada parecido; limítese a definirla y programarla. | |
| Ahora que ha visto el módulo os, esta línea debería tener más sentido. Toma la extensión del fichero (os.path.splitext(filename)[1]), fuerza a convertirla en mayúsculas (.upper()), le quita el punto ([1:]), y construye el nombre de una clase usando cadenas de formato. Así que c:\music\ap\mahadeva.mp3 se convierte en .mp3, y esto a su vez en .MP3 que acaba siendo MP3 para darnos MP3FileInfo. | |
| Habiendo construido el nombre de la clase controladora que manipulará este fichero, comprobamos si la clase existe realmente en este módulo. Si está, devuelve la clase, y si no, devuelve la clase base FileInfo. Éste es un detalle muy importante: esta función devuelve una clase. No una instancia de una clase, sino la propia clase. | |
| Por cada fichero de la lista “ficheros interesantes” (fileList), llamamos a getFileInfoClass pasándole el nombre del fichero (f). La invocación getFileInfoClass(f) devuelve una clase; que no sabemos exactamente cual es, pero no nos importa. Entonces creamos una instancia de esta clase (la que sea) y pasamos el nombre del fichero (f de nuevo) al método __init__. Como vio anteriormente en este capítulo, el método __init__ de FileInfo asigna self["name"], lo que dispara __setitem__, que está reemplazada en la clase descendiente (MP3FileInfo) para que analice el fichero de forma apropiada sacando los metadatos de su interior. Esto lo hacemos por cada fichero interesante y devolvemos una lista de las instancias resultantes. |
Observe que listDirectory es completamente genérica. No sabe nada con antelación sobre los tipos de ficheros con que va a trabajar, o qué clases están definidas que podrían potencialmente manipular estos ficheros. Inspecciona el directorio en busca de ficheros con que trabajar, y luego introspecciona en su propio módulo para ver qué clases manipuladoras (como MP3FileInfo) hay definidas. Puede extender este programa para manipular otros tipos de ficheros con solo definir una clase con el nombre apropiado: HTMLFileInfo para ficheros HTML, DOCFileInfo para ficheros .doc de Word, etc. listDirectory trabajará con todas, sin modificaciones, delegando el trabajo real a las clases apropiadas y recogiendo los resultados.
<< Trabajo con directorios |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
Resumen >> |