
Ceci est la cinquième sélection de conseils et de programmation Python de mon flux @pythonetc.
Sélections précédentes:
Séparateur -
Chaque utilitaire de ligne de commande décent doit accepter des arguments sous forme d'options (par exemple,
-h ou
--help ), des options avec des paramètres (
--log-niveau 2 ) ou des paramètres de position (
cp file1 file2 ).
Les options diffèrent des paramètres de position par la présence d'un ou deux tirets au début. Lorsque les arguments de position commencent par un tiret, des problèmes surviennent: si vous souhaitez supprimer un fichier nommé
-rf , la
commande rm -rf ne vous aidera pas.
Une solution simple consiste à utiliser deux tirets comme séparateur. Les arguments après - ne sont pas considérés comme des options:
$ 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
Deux tirets sont pris en charge par le module argparse hors de la boîte.
Stabilité du tri
Le tri standard en Python est robuste, la fonction
triée ne change pas l'ordre des objets égaux:
In : a = [2, -1, 0, 1, -2] In : sorted(a, key=lambda x: x**2) Out: [0, -1, 1, 2, -2]
Les fonctions
min et
max sont également cohérentes avec
triées. max fonctionne comme
trié (a, reverse = True) [0] , et
min fonctionne comme
trié ( a) [0] . Cela signifie que les deux fonctions renvoient la réponse la plus à gauche possible:
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
Cache dans l'argument par défaut
L'erreur la plus courante chez les pythonistes débutants est peut-être de spécifier un objet mutable comme argument de la fonction par défaut. La séparation de cet objet entre les appels de fonction peut conduire aux résultats les plus étranges:
def append_length(lst=[]): lst.append(len(lst)) return lst print(append_length([1, 2]))
Cependant, un tel partage sera même utile si vous utilisez l'objet pour créer un cache partagé:
def fact(x, cache={0: 1}): if x not in cache: cache[x] = x * fact(x - 1) return cache[x] print(fact(5))
Dans cet exemple, nous plaçons les valeurs factorielles calculées à l'intérieur des valeurs d'argument par défaut. De telles valeurs peuvent même être extraites:
>>> fact.__defaults__ ({0: 1, 1: 1, 2: 2, 3: 6, 4: 24, 5: 120},)
Travailler avec FS
Vous pouvez travailler avec des chemins de système de fichiers à l'aide du module
os.path . Le module contient de nombreuses fonctions qui traitent les chaînes comme des chemins de fichiers et effectuent diverses opérations utiles sur elles comme la concaténation:
>>> import os.path >>> os.path.join('/usr', 'local') '/usr/local' >>> os.path.dirname('/var/log') '/var'
À partir de la version 3.4, Python inclut un module
pathlib qui offre une approche orientée objet:
>>> 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'
Objets appelés
En Python, vous pouvez créer un objet appelable non seulement en créant des fonctions (en utilisant la syntaxe
def ou
lambda ). Un objet devient appelable s'il a une méthode
__call__ :
class Truncater: def __init__(self, length): self._length = length def __call__(self, s): return s[0:self._length] print(Truncater(4)('abcdabcd'))
Puisque le décorateur est essentiellement une fonction d'ordre supérieur, il peut également être exprimé par l'objet appelé, pas une fonction:
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