Parte 6
6.1. Excepciones
Ejemplos de excepciones no capturadas>>> di = {}
>>> di['uno']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'uno'
>>> lista = []
>>> lista[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> lista.index('x')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.index(x): x not in list
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> print "Numero: " + 6
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
>>> archivo = open('/hola', 'r')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: '/hola'
Python usa try... except para manejar excepciones y raise para generarlas. Del mismo modo que Java y C++ usan try... catch y throw.
>>> fsock = open("/notthere", "r")
Traceback (innermost last):
File "<interactive input>", line 1, in ?
IOError: [Errno 2] No such file or directory: '/notthere'
>>> try:
... fsock = open("/notthere")
... except IOError:
... print "The file does not exist, exiting gracefully"
... print "This line will always print"
The file does not exist, exiting gracefully
This line will always print
Mas alla de errores
def auth():
try:
from EasyDialogs import AskPassword
except ImportError:
try:
import msvcrt
except ImportError:
try:
import getpass
except ImportError:
getpass = raw_input
else:
getpass = getpass.getpass
else:
getpass = win_getpass
else:
getpass = unix_getpass
ps = getpass()
return ps
6.2. Archivos
>>> f = open("/music/_singles/kairo.mp3", "rb")
>>> f
<open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988>
>>> f.mode
'rb'
>>> f.name
'/music/_singles/kairo.mp3'
Leyendo archivos
>>> f
<open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988>
>>> f.tell()
0
>>> f.seek(-128, 2)
>>> f.tell()
7542909
>>> tagData = f.read(128)
>>> tagData
'TAGKAIRO****THE BEST GOA ***DJ MARY-JANE***
Rave Mix 2000http://mp3.com/DJMARYJANE \037'
>>> f.tell()
7543037
Cerrar archivos
>>> f
<open file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988>
>>> f.closed
False
>>> f.close()
>>> f
<closed file '/music/_singles/kairo.mp3', mode 'rb' at 010E3988>
>>> f.closed
True
>>> f.seek(0)
Traceback (innermost last):
File "<interactive input>", line 1, in ?
ValueError: I/O operation on closed file
>>> f.tell()
Traceback (innermost last):
File "<interactive input>", line 1, in ?
ValueError: I/O operation on closed file
>>> f.read()
Traceback (innermost last):
File "<interactive input>", line 1, in ?
ValueError: I/O operation on closed file
>>> f.close()
Capturando excepciones de I/O
try:
fsock = open(filename, "rb", 0)
try:
fsock.seek(-128, 2)
tagdata = fsock.read(128)
finally:
fsock.close()
.
.
.
except IOError:
pass
Escribiendo archivos
>>> logfile = open('test.log', 'w')
>>> logfile.write('test succeeded')
>>> logfile.close()
>>> print file('test.log').read()
test succeeded
>>> logfile = open('test.log', 'a')
>>> logfile.write('line 2')
>>> logfile.close()
>>> print file('test.log').read()
test succeededline 2
6.3. sys.modules
>>> import sys
>>> print '\n'.join(sys.modules.keys())
win32api
os.path
os
exceptions
__main__
ntpath
nt
sys
__builtin__
site
signal
UserDict
stat
>>> sys.version
'2.5.1 (r251:54863, Mar 7 2008, 03:41:45) \n[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)]'
>>> sys.version_info
(2, 5, 1, 'final', 0)
>>> sys.setrecursionlimit(2000)
>>>
- sys.modules es u diccionario que contiene todos los módulos que han sido importados desde que Python fue iniciado. La clave es el nombre del módulo, el valor es el objeto-modulo.
>>> from apihelper import infoCombinado con sys.module se puede conseguir una referencia al módulo que define el método
>>> info.__module__
'apihelper'
>>> sys.modules[info.__module__]
<module 'apihelper' from 'apihelper.pyc'>
6.4. Directorios
Construcción de paths
>>> import os
>>> os.path.join.__doc__
"Join two or more pathname components, inserting '/' as needed"
>>> os.path.join("/music/ap/", "mahadeva.mp3")
'/music/ap/mahadeva.mp3'
>>> os.path.join("/music/ap", "mahadeva.mp3")
'/music/ap/mahadeva.mp3'
>>> os.path.expanduser("~")
'/home/rover'
>>> os.path.join(os.path.expanduser("~"), "Python")
'/home/rover/Python'
>>> os.path.join("c:\\music\\ap\\", "mahadeva.mp3")
'c:\\music\\ap\\mahadeva.mp3'
>>> os.path.join("c:\\music\\ap", "mahadeva.mp3")
'c:\\music\\ap\\mahadeva.mp3'
>>> os.path.expanduser("~")
'c:\\Documents and Settings\\mpilgrim\\My Documents'
>>> os.path.join(os.path.expanduser("~"), "Python")
'c:\\Documents and Settings\\mpilgrim\\My Documents\\Python'
División de paths
>>> os.path.split.__doc__
'Split a pathname. Returns tuple "(head, tail)" where "tail" is\n everything after the final slash. Either part may be empty.'
>>> os.path.split("/music/ap/mahadeva.mp3")
('/music/ap', 'mahadeva.mp3')
>>> (filepath, filename) = os.path.split("/music/ap/mahadeva.mp3")
>>> filepath
'/music/ap'
>>> filename
'mahadeva.mp3'
>>> (shortname, extension) = os.path.splitext(filename)
>>> shortname
'mahadeva'
>>> extension
'.mp3'
>>> os.path.split("c:\\music\\ap\\mahadeva.mp3")
('c:\\music\\ap', 'mahadeva.mp3')
>>> (filepath, filename) = os.path.split("c:\\music\\ap\\mahadeva.mp3")
>>> filepath
'c:\\music\\ap'
>>> filename
'mahadeva.mp3'
>>> (shortname, extension) = os.path.splitext(filename)
>>> shortname
'mahadeva'
>>> extension
'.mp3'
Listando directorios
>>> os.listdir("/home/music")
['a_time_long_forgotten_con.mp3', 'hellraiser.mp3',
'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3',
'spinning.mp3']
>>> os.listdir(dirname)
['media', 'opt', 'sbin', 'proc', 'etc', 'initrd', 'tmp', 'dev', 'srv', 'initrd.img', 'bin', 'root',
'lib', 'var', 'mnt', 'lost+found', 'vmlinuz', 'boot', 'home', 'usr', 'cdrom', 'sys']
>>> [f for f in os.listdir(dirname)
... if os.path.isfile(os.path.join(dirname, f))]
['initrd.img', 'vmlinuz']
>>> [f for f in os.listdir(dirname)
... if os.path.isdir(os.path.join(dirname, f))]
['media', 'opt', 'sbin', 'proc', 'etc', 'initrd', 'tmp', 'dev', 'srv', 'bin', 'root', 'lib', 'var',
'mnt', 'lost+found', 'boot', 'home', 'usr', 'cdrom', 'sys']
>>> os.listdir("c:\\music\\_singles\\")
['a_time_long_forgotten_con.mp3', 'hellraiser.mp3',
'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3',
'spinning.mp3']
>>> dirname = "c:\\"
>>> os.listdir(dirname)
['AUTOEXEC.BAT', 'boot.ini', 'CONFIG.SYS', 'cygwin',
'docbook', 'Documents and Settings', 'Incoming', 'Inetpub', 'IO.SYS',
'MSDOS.SYS', 'Music', 'NTDETECT.COM', 'ntldr', 'pagefile.sys',
'Program Files', 'Python20', 'RECYCLER',
'System Volume Information', 'TEMP', 'WINNT']
>>> [f for f in os.listdir(dirname)
... if os.path.isfile(os.path.join(dirname, f))]
['AUTOEXEC.BAT', 'boot.ini', 'CONFIG.SYS', 'IO.SYS', 'MSDOS.SYS',
'NTDETECT.COM', 'ntldr', 'pagefile.sys']
>>> [f for f in os.listdir(dirname)
... if os.path.isdir(os.path.join(dirname, f))]
['cygwin', 'docbook', 'Documents and Settings', 'Incoming',
'Inetpub', 'Music', 'Program Files', 'Python20', 'RECYCLER',
'System Volume Information', 'TEMP', 'WINNT']
definiendo una función para listar directorios según extensión
import os
def listDirectory(directory, fileExtList):
"get list of file info objects for files of particular extensions"
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]
return fileList
>>> from list import listDirectory
>>> listDirectory('/', [''])
['/media', '/opt', '/sbin', '/proc', '/etc', '/initrd', '/tmp', '/dev', '/srv', '/bin', '/root', '/lib',
'/var', '/mnt', '/lost+found', '/vmlinuz', '/boot', '/home', '/usr', '/cdrom', '/sys']
>>> listDirectory('/home/music', ['.mp3'])
['a_time_long_forgotten_con.mp3', 'hellraiser.mp3',
'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3',
'spinning.mp3']
Usando glob
>>> os.listdir("c:\\music\\_singles\\")
['a_time_long_forgotten_con.mp3', 'hellraiser.mp3',
'kairo.mp3', 'long_way_home1.mp3', 'sidewinder.mp3',
'spinning.mp3']
>>> import glob
>>> glob.glob('c:\\music\\_singles\\*.mp3')
['c:\\music\\_singles\\a_time_long_forgotten_con.mp3',
'c:\\music\\_singles\\hellraiser.mp3',
'c:\\music\\_singles\\kairo.mp3',
'c:\\music\\_singles\\long_way_home1.mp3',
'c:\\music\\_singles\\sidewinder.mp3',
'c:\\music\\_singles\\spinning.mp3']
>>> glob.glob('c:\\music\\_singles\\s*.mp3')
['c:\\music\\_singles\\sidewinder.mp3',
'c:\\music\\_singles\\spinning.mp3']
>>> glob.glob('c:\\music\\*\\*.mp3')
Ejemplo integrador
"""Framework for getting filetype-specific metadata.
Instantiate appropriate class with filename. Returned object acts like a
dictionary, with key-value pairs for each piece of metadata.
import fileinfo
info = fileinfo.MP3FileInfo("/music/ap/mahadeva.mp3")
print "\\n".join(["%s=%s" % (k, v) for k, v in info.items()])
Or use listDirectory function to get info on all files in a directory.
for info in fileinfo.listDirectory("/music/ap/", [".mp3"]):
...
Framework can be extended by adding classes for particular file types, e.g.
HTMLFileInfo, MPGFileInfo, DOCFileInfo. Each class is completely responsible for
parsing its files appropriately; see MP3FileInfo for example.
"""
import os
import sys
from UserDict import UserDict
def stripnulls(data):
"strip whitespace and nulls"
return data.replace("\00", "").strip()
class FileInfo(UserDict):
"store file metadata"
def __init__(self, filename=None):
UserDict.__init__(self)
self["name"] = filename
class MP3FileInfo(FileInfo):
"store ID3v1.0 MP3 tags"
tagDataMap = {"title" : ( 3, 33, stripnulls),
"artist" : ( 33, 63, stripnulls),
"album" : ( 63, 93, stripnulls),
"year" : ( 93, 97, stripnulls),
"comment" : ( 97, 126, stripnulls),
"genre" : (127, 128, ord)}
def __parse(self, filename):
"parse ID3v1.0 tags from MP3 file"
self.clear()
try:
fsock = open(filename, "rb", 0)
try:
fsock.seek(-128, 2)
tagdata = fsock.read(128)
finally:
fsock.close()
if tagdata[:3] == "TAG":
for tag, (start, end, parseFunc) in self.tagDataMap.items():
self[tag] = parseFunc(tagdata[start:end])
except IOError:
pass
def __setitem__(self, key, item):
if key == "name" and item:
self.__parse(item)
FileInfo.__setitem__(self, key, item)
def listDirectory(directory, fileExtList):
"get list of file info objects for files of particular extensions"
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__]):
"get file info class from filename extension"
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]
if __name__ == "__main__":
for info in listDirectory("/music/_singles/", [".mp3"]):
print "\n".join(["%s=%s" % (k, v) for k, v in info.items()])
6.5. Strings
Búsqueda
>>> ubuntu = 'Ubuntu es un GNU/Linux'
>>> print ubuntu.index.__doc__
S.index(sub [,start [,end]]) -> int
Like S.find() but raise ValueError when the substring is not found.
>>> ubuntu[17]
'L'
>>> ubuntu[17:17+len('linux')]
'Linux'
>>> ubuntu.index('sss')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
>>> ubuntu.find('aaa')
-1
>>> print ubuntu.count.__doc__
S.count(sub[, start[, end]]) -> int
Return the number of non-overlapping occurrences of substring sub in
string S[start:end]. Optional arguments start and end are interpreted
as in slice notation.
>>> print ubuntu.count('Linux')
1
Reemplazo
>>> ubuntu[0:17] + ubuntu[17:17+len('linux')] + ubuntu[17+len('linux'):]
'Ubuntu es un GNU/Linux y software libre'
>>> ubuntu[0:17] + 'BSD' + ubuntu[17+len('linux'):]
'Ubuntu es un GNU/BSD y software libre'
>>> ubuntu.replace('Linux','BSD')
'Ubuntu es un GNU/BSD y software libre'
>>>
Parsing
>>> ubuntu.split()
['Ubuntu', 'es', 'un', 'GNU/Linux', 'y', 'software', 'libre']
>>> for elem in ubuntu.split():
... if elem == 'Linux':
... elem = 'BSD'
... result += elem
...
>>> result
'UbuntuesunGNU/Linuxysoftwarelibre'
Mayúsculas y minúsculas
>>> for elem in ubuntu.split():
... if elem.lower() == 'linux':
... elem = 'BSD'
... result += elem
...
>>> result
'UbuntuesunGNU/Linuxysoftwarelibre'
>>> for elem in ubuntu.split():
... if elem.upper() == 'linux':
... elem = 'BSD'
... result += elem
...
>>> result
'UbuntuesunGNU/Linuxysoftwarelibre'
Otras búsquedas
>> s = '100 NORTH MAIN ROAD'
>>> s.replace('ROAD', 'RD.')
'100 NORTH MAIN RD.'
>>> s = '100 NORTH BROAD ROAD'
>>> s.replace('ROAD', 'RD.')
'100 NORTH BRD. RD.'
>>> s[:-4] + s[-4:].replace('ROAD', 'RD.')
'100 NORTH BROAD RD.'
>>> import re
>>> re.sub('ROAD$', 'RD.', s)
'100 NORTH BROAD RD.'
Ejercicios
- Probar fileinfo con archivos mp3. Estudiar su funcionamiento
- Proveer soporte a los ejercicios de la parte anterior (equipos y club) para almacenar los objetos creados en un archivos de modo que se cierre el programa y al abrirlo de nuevo se encuentren los datos de la sesion anterior.
- Estudiar las diferentes tipos de excepciones que provee python (usar pydoc)