@Pythonetc Octubre 2018

imagen

Esta es la quinta selección de consejos y programación de Python de mi feed @pythonetc.

Selecciones anteriores:



Separador -


Cada utilidad de línea de comandos decente debe aceptar argumentos en forma de opciones (por ejemplo, -h o --help ), opciones con parámetros ( --log-level 2 ) o parámetros posicionales ( cp file1 file2 ).

Las opciones difieren de los parámetros posicionales por la presencia de uno o dos guiones al principio. Cuando los argumentos posicionales comienzan con un guión, surgen problemas: si desea eliminar un archivo llamado -rf , entonces el comando rm -rf no lo ayudará con esto.

Una salida fácil es usar dos guiones como separador. Los argumentos posteriores a - no se consideran opciones:

$ echo test > -rf $ cat -rf cat: invalid option -- 'r' Try 'cat --help' for more information. $ cat -- -rf test $ rm -- -rf $ cat -- -rf cat: -rf: No such file or directory 

El módulo argparse admite dos guiones listos para usar.

Ordenar la estabilidad


La ordenación estándar en Python es robusta, la función ordenada no cambia el orden de los objetos iguales:

 In : a = [2, -1, 0, 1, -2] In : sorted(a, key=lambda x: x**2) Out: [0, -1, 1, 2, -2] 

Las funciones min y max también son consistentes con las ordenadas. max funciona como ordenado (a, reverse = True) [0] , y min funciona como ordenado ( a) [0] . Esto significa que ambas funciones devuelven la respuesta más a la izquierda posible:

 In : max([2, -2], key=lambda x: x**2) Out: 2 In : max([-2, 2], key=lambda x: x**2) Out: -2 In : min([2, -2], key=lambda x: x**2) Out: 2 In : min([-2, 2], key=lambda x: x**2) Out: -2 

Caché en argumento predeterminado


Quizás el error más común entre los pitonistas novatos es especificar un objeto mutable como argumento para la función predeterminada. Separar este objeto entre llamadas a funciones puede conducir a los resultados más extraños:

 def append_length(lst=[]): lst.append(len(lst)) return lst print(append_length([1, 2])) # [1, 2, 2] print(append_length()) # [0] print(append_length()) # [0, 1] 

Sin embargo, este uso compartido incluso será útil si usa el objeto para crear un caché compartido:

 def fact(x, cache={0: 1}): if x not in cache: cache[x] = x * fact(x - 1) return cache[x] print(fact(5)) 

En este ejemplo, colocamos los valores factoriales calculados dentro de los valores de argumento predeterminados. Tales valores pueden incluso extraerse:

 >>> fact.__defaults__ ({0: 1, 1: 1, 2: 2, 3: 6, 4: 24, 5: 120},) 

Trabajar con FS


Puede trabajar con rutas de sistema de archivos utilizando el módulo os.path . El módulo contiene muchas funciones que tratan las cadenas como rutas de archivos y realizan varias operaciones útiles en ellas como la concatenación:

 >>> import os.path >>> os.path.join('/usr', 'local') '/usr/local' >>> os.path.dirname('/var/log') '/var' 

A partir de la versión 3.4, Python incluye un módulo pathlib que ofrece un enfoque orientado a objetos:

 >>> from pathlib import Path >>> Path('/usr') / Path('local') PosixPath('/usr/local') >>> Path('/usr') / 'local' PosixPath('/usr/local') >>> Path('/var/log').parent PosixPath('/var') >>> Path('/var/log').parent.name 'var' 

Objetos llamados


En Python, puede crear un objeto invocable no solo creando funciones (usando la sintaxis def o lambda ). Un objeto se puede llamar si tiene un método __call__ :

 class Truncater: def __init__(self, length): self._length = length def __call__(self, s): return s[0:self._length] print(Truncater(4)('abcdabcd')) # abcd 

Dado que el decorador es esencialmente una función de orden superior, también puede expresarse por el objeto llamado, no por una función:

 class cached: def __init__(self, func): self._func = func self._cache = {} def __call__(self, arg): if arg not in self._cache: self._cache[arg] = self._func(arg) return self._cache[arg] @cached def sqr(x): return x * x 

Source: https://habr.com/ru/post/es429186/


All Articles