Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
script:python:new:api [2013/08/14 11:25] alfred [Parámetros del ejecutable] |
script:python:new:api [2020/05/09 09:25] (actual) |
||
|---|---|---|---|
| Línea 75: | Línea 75: | ||
| <code python> | <code python> | ||
| str = 'Name: {user.name}, Age: {user.age}, Sex: {user.sex}'.format(user=user) | str = 'Name: {user.name}, Age: {user.age}, Sex: {user.sex}'.format(user=user) | ||
| + | </code> | ||
| + | Podemos hacer uso de ''!s'' y ''!r'' que llaman al str() y al repr() del objeto. Combinándolo queda: | ||
| + | <code python> | ||
| + | subscriber.connect("tcp://127.0.0.1:{port!s}".format(port=ZPORT)) | ||
| + | subscriber.connect("tcp://127.0.0.1:{0!s}".format(ZPORT)) | ||
| </code> | </code> | ||
| Línea 96: | Línea 100: | ||
| </code> | </code> | ||
| * Existen funciones para el [[script:python:new:api#expresiones_regulares|tratamiento de expresiones regulares]]. | * Existen funciones para el [[script:python:new:api#expresiones_regulares|tratamiento de expresiones regulares]]. | ||
| - | |||
| Línea 162: | Línea 165: | ||
| import os | import os | ||
| os.path.abspath(rel_path) # Devuelve el path absoluto al que apunta rel_path | os.path.abspath(rel_path) # Devuelve el path absoluto al que apunta rel_path | ||
| + | os.path.basename(obs_path) # Devuelve el nombre del fichero | ||
| os.mkdir(path) # Crea un directorio | os.mkdir(path) # Crea un directorio | ||
| os.sep # Devuelve el separador de directorios del sistema | os.sep # Devuelve el separador de directorios del sistema | ||
| Línea 178: | Línea 182: | ||
| shutil.copyfile(src, dst) # Copia un fichero | shutil.copyfile(src, dst) # Copia un fichero | ||
| shutil.move(src, dst) # Mueve un fichero | shutil.move(src, dst) # Mueve un fichero | ||
| + | </code> | ||
| + | === Recorrer árbol de directorios === | ||
| + | <code python> | ||
| + | import os | ||
| + | path = raw_input("Specify a folder that you want to perform an 'os.walk' on: >> ") | ||
| + | for root, dirs, files in os.walk(path): | ||
| + | print root | ||
| + | print dirs | ||
| + | print files | ||
| + | print "---------------" | ||
| </code> | </code> | ||
| ==== Parámetros del ejecutable ==== | ==== Parámetros del ejecutable ==== | ||
| === Argparse === | === Argparse === | ||
| + | * [[http://docs.python.org/dev/library/argparse.html|Documentación]] | ||
| + | |||
| + | <code python> | ||
| + | from argparse import ArgumentParser | ||
| + | parser = ArgumentParser() | ||
| + | parser.add_argument('-f', '--foo', dest='foo', help='foo help') | ||
| + | args = parser.parse_args() | ||
| + | print args.foo | ||
| + | </code> | ||
| + | ''add_argument'' permite, entre otros, los siguientes parámetros: | ||
| + | * ''name'' o ''flags'': un nombre o lista de opciones, ejemplos: ''<nowiki>foo, -f, --foo</nowiki>'' | ||
| + | * ''action'': una acción especial para ese argumento (ver ayuda). | ||
| + | * ''store_true'' o ''store_false'': ''store_true'' significa que si se especifica la opción entonces se asignará ''True'' al valor de este: ''parser.add_argument("--verbose", help="increase output verbosity", action="store_true")'' | ||
| + | * ''default'': el valor por defecto. | ||
| + | * ''parser.add_argument('--foo', default=42)'' | ||
| + | * ''type'': el tipo de la variable. | ||
| + | * ''parser.add_argument('--foo', type=int)'' | ||
| + | * ''choices'': posibles opciones: | ||
| + | * ''parser.add_argument('foo', type=int, choices=range(5, 10))'' | ||
| + | * ''parser.add_argument('move', choices=['rock', 'paper', 'scissors'])'' | ||
| + | * ''required'': indica si el argumento es obligatorio | ||
| + | * ''parser.add_argument('--foo', required=True)'' | ||
| + | * ''help'': texto de ayuda | ||
| + | * ''metavar'': el nombre del argumento dentro de la ayuda. | ||
| + | * ''dest'': el atributo de destino. | ||
| + | El constructor de ''ArgumentParser'' acepta los siguientes parámetros: | ||
| + | * ''prog'': el nombre dle programa. | ||
| + | * ''usage'': el string de ayuda. | ||
| + | * ''parents'': array de ArgumentParser de los cuales sus argumentos se incluirán junto con los de este. | ||
| === OptionParse === | === OptionParse === | ||
| - | :!: Deprecated! \\ | + | * :!: Deprecated! |
| Se utiliza el objeto ''OptionParse'' del paquete ''optparse'' | Se utiliza el objeto ''OptionParse'' del paquete ''optparse'' | ||
| <code python> | <code python> | ||
| Línea 447: | Línea 490: | ||
| c1.close() # cerramos la primera conexión | c1.close() # cerramos la primera conexión | ||
| </code> | </code> | ||
| + | Al hacer el connect podemos conectar con una DB ficticia en memoria usando ''":memory:"''. | ||
| === Insertar una fecha === | === Insertar una fecha === | ||
| <code python> | <code python> | ||
| Línea 463: | Línea 506: | ||
| db.commit() | db.commit() | ||
| </code> | </code> | ||
| - | |||
| ==== Datos binarios ==== | ==== Datos binarios ==== | ||
| Línea 535: | Línea 577: | ||
| ==== Logging ==== | ==== Logging ==== | ||
| + | * [[http://docs.python.org/2/library/logging.html]] | ||
| Niveles de log: ''DEBUG'', ''INFO'', ''WARNING'', ''ERROR'', ''CRITICAL'' \\ | Niveles de log: ''DEBUG'', ''INFO'', ''WARNING'', ''ERROR'', ''CRITICAL'' \\ | ||
| El nivel por defecto es ''WARNING''. \\ | El nivel por defecto es ''WARNING''. \\ | ||
| Línea 623: | Línea 666: | ||
| datefmt= | datefmt= | ||
| </code> | </code> | ||
| + | |||
| + | === Para mostrar información de la excepción === | ||
| + | <code python> | ||
| + | try: | ||
| + | open('/path/to/does/not/exist', 'rb') | ||
| + | except (SystemExit, KeyboardInterrupt): | ||
| + | raise | ||
| + | except Exception, e: | ||
| + | logger.error('Failed to open file', exc_info=True) | ||
| + | </code> | ||
| + | |||
| + | === Notas === | ||
| + | Desactivar el log: | ||
| + | <code python> | ||
| + | logging.getLogger().disabled = True | ||
| + | </code> | ||
| + | |||
| + | |||
| ==== Imports dinámicos ==== | ==== Imports dinámicos ==== | ||
| A partir del módulo ''imp'' podemos realizar imports por código. Este módulo tiene funciones como... | A partir del módulo ''imp'' podemos realizar imports por código. Este módulo tiene funciones como... | ||
| * ''load_module'' para cargar el módulo. | * ''load_module'' para cargar el módulo. | ||
| - | ===== Otros ===== | ||
| + | También podemos hacerlo: | ||
| + | <code python> | ||
| + | mod = __import__(name_module) | ||
| + | cls = getattr(mod, name_class) | ||
| + | </code> | ||
| + | |||
| + | O importar una ruta: | ||
| + | <code python> | ||
| + | def import_path (mpath): | ||
| + | from imp import load_source | ||
| + | from os import path | ||
| + | fname = path.basename(obs_path)[:-3] | ||
| + | return load_source(fname, mpath) | ||
| + | </code> | ||
| + | |||
| + | === Otra forma de importar === | ||
| + | Si la aplicación se abre desde, por ejemplo, otro path. | ||
| + | <code python> | ||
| + | import sys | ||
| + | from os.path import abspath | ||
| + | sys.path.append(abspath('.')) | ||
| + | from backend.css.tasks import parse_grammar | ||
| + | </code> | ||
| + | ==== UnitTesting ==== | ||
| + | * Deberemos hacer un import de ''unittest''. | ||
| + | * Las clases que implementen los tests heredarán ''unittest.TestCase''. | ||
| + | * Los tests serán los métodos de dicha clase, por convención su nombre empezará por ''test_''. | ||
| + | * Los ficheros de test también deberán tener un nombre que empiece por ''test_''. | ||
| + | * El método ''setUp(self)'' se ejecuta antes de cada test. | ||
| + | * El método ''tearDown(self)'' se ejecuta después de cada test. | ||
| + | * El siguiente comando realizará los tests dentro de ese directorio: | ||
| + | <code> | ||
| + | $ python -m unittest discover | ||
| + | </code> | ||
| + | * Otras formas de ejecutar tests: | ||
| + | <code> | ||
| + | $ python -m unittest test_random | ||
| + | $ python -m unittest test_random.TestSequenceFunctions | ||
| + | $ python -m unittest test_random.TestSequenceFunctions.test_shuffle | ||
| + | </code> | ||
| + | * Las comprobaciones que se pueden hacer son: | ||
| + | * ''assertEqual(expected, actual)'' | ||
| + | * ''assertNotEqual(notExpected, actual)'' | ||
| + | * ''assertTrue(expression)'' y ''assertFalse(expression)'' | ||
| + | * ''assertIsInstance(object, class)'' | ||
| + | |||
| + | <code python> | ||
| + | ''' | ||
| + | RULES OF TENNIS | ||
| + | * Each player can have either of these points in one game, described as 0-15-30-40. Each time a player scores, it advances of one position in the scale. | ||
| + | * A player at 40 who scores wins the set. Unless... | ||
| + | * If both players are at 40, we are in a *deuce*. If the game is in deuce, the next scoring player will gain an *advantage*. Then if the player in advantage scores he wins, while if the player not in advantage scores they are back at deuce. | ||
| + | ''' | ||
| + | from tennis import Set, Scores | ||
| + | from unittest import TestCase | ||
| + | |||
| + | class TestSetWinning(TestCase): | ||
| + | def test_score_grows(self): | ||
| + | set = Set() | ||
| + | self.assertEqual("0", set.firstScore()) | ||
| + | set.firstScores() | ||
| + | self.assertEqual("15", set.firstScore()) | ||
| + | self.assertEqual("0", set.secondScore()) | ||
| + | set.secondScores() | ||
| + | self.assertEqual("15", set.secondScore()) | ||
| + | def test_player_1_win_when_scores_at_40(self): | ||
| + | set = Set() | ||
| + | set.firstScores(3) | ||
| + | self.assertEqual(None, set.winner()) | ||
| + | set.firstScores() | ||
| + | self.assertEqual(1, set.winner()) | ||
| + | def test_player_2_win_when_scores_at_40(self): | ||
| + | set = Set() | ||
| + | set.secondScores(3) | ||
| + | self.assertEqual(None, set.winner()) | ||
| + | set.secondScores() | ||
| + | self.assertEqual(2, set.winner()) | ||
| + | def test_deuce_requires_1_more_than_one_ball_to_win(self): | ||
| + | set = Set() | ||
| + | set.firstScores(3) | ||
| + | set.secondScores(3) | ||
| + | set.firstScores() | ||
| + | self.assertEqual(None, set.winner()) | ||
| + | set.firstScores() | ||
| + | self.assertEqual(1, set.winner()) | ||
| + | def test_deuce_requires_2_more_than_one_ball_to_win(self): | ||
| + | set = Set() | ||
| + | set.firstScores(3) | ||
| + | set.secondScores(3) | ||
| + | set.secondScores() | ||
| + | self.assertEqual(None, set.winner()) | ||
| + | set.secondScores() | ||
| + | self.assertEqual(2, set.winner()) | ||
| + | def test_player_can_return_to_deuce_by_scoring_against_the_others_advantage(self): | ||
| + | set = Set() | ||
| + | set.firstScores(3) | ||
| + | set.secondScores(3) | ||
| + | self.assertEqual(None, set.winner()) | ||
| + | set.firstScores() | ||
| + | set.secondScores() | ||
| + | set.firstScores() | ||
| + | set.secondScores() | ||
| + | self.assertEqual(None, set.winner()) | ||
| + | self.assertEqual("40", set.firstScore()) | ||
| + | self.assertEqual("40", set.secondScore()) | ||
| + | |||
| + | class TestScoreNames(TestCase): | ||
| + | def test_score_names(self): | ||
| + | scores = Scores() | ||
| + | self.assertEqual("0", scores.scoreName(0)) | ||
| + | self.assertEqual("15", scores.scoreName(1)) | ||
| + | self.assertEqual("30", scores.scoreName(2)) | ||
| + | self.assertEqual("40", scores.scoreName(3)) | ||
| + | self.assertEqual("A", scores.scoreName(4)) | ||
| + | </code> | ||
| + | |||
| + | === Notas === | ||
| + | * [[https://wiki.python.org/moin/PythonTestingToolsTaxonomy|Librerías de TDD]] | ||
| + | ===== Otros ===== | ||