Trucs et astuces de ma chaîne Telegram @pythonetc, novembre 2019
C'est une nouvelle sélection de trucs et astuces sur Python et la programmation de mon canal Telegram @pythonetc.
←
Publications précédentes .
PATH
est une variable d'environnement qui stocke les chemins où les exécutables sont recherchés. Lorsque vous demandez à votre shell d'exécuter
ls
, le shell recherche le fichier exécutable
ls
sur tous les chemins d'accès présentés dans PATH.
$ echo $PATH /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/v.pushtaev/.local/bin:/home/v.pushtaev/bin $ which ls /usr/bin/ls
Dans l'exemple ci-dessus, les chemins sont séparés par
:
dans PATH. Aucun échappement n'est possible: un chemin qui contient
:
ne peut pas être utilisé dans
PATH
.
Cependant, ce n'est pas vrai pour tous les systèmes d'exploitation. En Python, vous pouvez obtenir le bon séparateur pour le système local avec
os.pathsep
:
Python 3.5.0 [...] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> os.pathsep ';'
os.pathsep
ne doit pas être mélangé avec
os.path.sep
qui est le séparateur des chemins de fichiers:
>>> os.path.sep '/'
Pour rendre les expressions régulières plus lisibles, vous pouvez utiliser l'indicateur
re.VERBOSE
. Il vous permet d'utiliser des espaces supplémentaires où vous le souhaitez et d'ajouter des commentaires avec le symbole
#
:
import re URL_RE = re.compile(r''' ^ (https?):// (www[.])? ( (?: [^.]+[.] )+ ( [^/]+ ) # TLD ) (/.*) $ ''', re.VERBOSE) m = URL_RE.match('https://www.pythonetc.com/about/') schema, www, domain, tld, path = m.groups() has_www: bool = bool(www) print(f'schema={schema}, has_www={has_www}') print(f'domain={domain}, tld={tld}') print(f'path={path}')
re.X
est un alias pour
re.VERBOSE
.
complex
est le type intégré Python pour les nombres complexes:
>>> complex(1, 2).real 1.0 >>> abs(complex(3, 4)) 5.0 >>> complex(1, 2) == complex(1, -2).conjugate() True >>> str(complex(2, -3)) '(2-3j)'
Il n'est pas nécessaire de l'utiliser directement, car Python a des littéraux pour les nombres complexes:
>>> (3 + 4j).imag 4.0 >>> not (3 + 4j) False >>> (-3 - 4j) + (2 - 2j) (-1-6j)
a : b : c
notation a
a : b : c
peut être utilisée pour définir la
slice(a, b, c)
uniquement entre crochets:
>>> [1, 2, 3, 4, 5][0:4:2] [1, 3] >>> [1, 2, 3, 4, 5][slice(0, 4, 2)] [1, 3]
Si vous souhaitez passer l'objet tranche comme argument à une fonction, vous devez le définir explicitement:
def multislice(slc, *iterables): return [i[slc] for i in iterables] print(multislice( slice(2, 6, 2), [1, 2, 3, 4, 5, 6, 7], [2, 4, 2, 4, 2, 4, 2], ))
Voici comment convertir une telle fonction en un objet qui prend en charge
[a : b : c]
:
from functools import partial class SliceArgDecorator: def __init__(self, f): self._f = f def __getitem__(self, slc): return partial(self._f, slc) slice_arg = SliceArgDecorator @slice_arg def multislice(slc, *iterables): return [i[slc] for i in iterables] print(multislice[2:6:2]( [1, 2, 3, 4, 5, 6, 7], [2, 4, 2, 4, 2, 4, 2], ))
__getattribute__
est un outil puissant qui vous permet d'utiliser facilement le modèle de délégation lorsque cela est approprié. Voici comment ajouter une capacité à être comparable à un objet non comparable:
class CustomEq: def __init__(self, orig, *, key): self._orig = orig self._key = key def __lt__(self, other): return self._key(self) < self._key(other) def __getattribute__(self, name): if name in {'_key', '_orig', '__lt__'}: return super().__getattribute__(name) return getattr(self._orig, name) class User: def __init__(self, user_id): self._user_id = user_id def get_user_id(self): return self._user_id def comparable(obj, *, key): return CustomEq(obj, key=key) user1 = comparable(User(1), key=lambda u: u.get_user_id()) user2 = comparable(User(2), key=lambda u: u.get_user_id()) print(user2 > user1)