Question Les fonctionnalités cachées de Python [fermé]


Quelles sont les fonctionnalités moins connues mais utiles du langage de programmation Python?

  • Essayez de limiter les réponses au noyau Python.
  • Une fonctionnalité par réponse.
  • Donnez un exemple et une brève description de la fonctionnalité, pas seulement un lien vers la documentation.
  • Étiquetez la fonction en utilisant un titre comme première ligne.

Liens rapides aux réponses:


1420


origine


Réponses:


Chaînes de comparaison d'opérateurs:

>>> x = 5
>>> 1 < x < 10
True
>>> 10 < x < 20 
False
>>> x < 10 < x*10 < 100
True
>>> 10 > x <= 9
True
>>> 5 == x > 4
True

Au cas où vous pensez que ça va 1 < x, qui sort comme True, puis en comparant True < 10, qui est aussi True, alors non, ce n'est vraiment pas ce qui se passe (voir le dernier exemple.) Cela se traduit vraiment par 1 < x and x < 10, et x < 10 and 10 < x * 10 and x*10 < 100, mais avec moins de dactylographie et chaque terme n'est évalué qu'une seule fois.


741



Obtenez l'arbre d'analyse de python regex pour déboguer votre regex.

Les expressions régulières sont une grande fonctionnalité de python, mais les déboguer peut être pénible, et il est trop facile de se tromper d'une regex.

Heureusement, python peut imprimer l'arbre d'analyse regex en passant le drapeau caché, expérimental et caché. re.DEBUG (en fait, 128) à re.compile.

>>> re.compile("^\[font(?:=(?P<size>[-+][0-9]{1,2}))?\](.*?)[/font]",
    re.DEBUG)
at at_beginning
literal 91
literal 102
literal 111
literal 110
literal 116
max_repeat 0 1
  subpattern None
    literal 61
    subpattern 1
      in
        literal 45
        literal 43
      max_repeat 1 2
        in
          range (48, 57)
literal 93
subpattern 2
  min_repeat 0 65535
    any None
in
  literal 47
  literal 102
  literal 111
  literal 110
  literal 116

Une fois que vous avez compris la syntaxe, vous pouvez repérer vos erreurs. Là, nous pouvons voir que j'ai oublié d'échapper à la [] dans [/font].

Bien sûr, vous pouvez le combiner avec tous les drapeaux que vous voulez, comme les regexes commentées:

>>> re.compile("""
 ^              # start of a line
 \[font         # the font tag
 (?:=(?P<size>  # optional [font=+size]
 [-+][0-9]{1,2} # size specification
 ))?
 \]             # end of tag
 (.*?)          # text between the tags
 \[/font\]      # end of the tag
 """, re.DEBUG|re.VERBOSE|re.DOTALL)

512



énumérer

Envelopper un itérable avec enumerate et il donnera l'article avec son index.

Par exemple:


>>> a = ['a', 'b', 'c', 'd', 'e']
>>> for index, item in enumerate(a): print index, item
...
0 a
1 b
2 c
3 d
4 e
>>>

Les références:


460



Créer des objets générateurs

Si vous écrivez

x=(n for n in foo if bar(n))

vous pouvez sortir le générateur et l'assigner à x. Maintenant, cela signifie que vous pouvez faire

for n in x:

L'avantage de ceci est que vous n'avez pas besoin de stockage intermédiaire, dont vous auriez besoin si vous le faisiez

x = [n for n in foo if bar(n)]

Dans certains cas, cela peut entraîner une accélération significative.

Vous pouvez ajouter plusieurs instructions if à la fin du générateur, répliquant en principe les boucles imbriquées:

>>> n = ((a,b) for a in range(0,2) for b in range(4,6))
>>> for i in n:
...   print i 

(0, 4)
(0, 5)
(1, 4)
(1, 5)

419



iter () peut prendre un argument appelable

Par exemple:

def seek_next_line(f):
    for c in iter(lambda: f.read(1),'\n'):
        pass

le iter(callable, until_value) fonction appels répétés callable et donne son résultat jusqu'à until_value est retourné.


353



Soyez prudent avec les arguments par défaut mutables

>>> def foo(x=[]):
...     x.append(1)
...     print x
... 
>>> foo()
[1]
>>> foo()
[1, 1]
>>> foo()
[1, 1, 1]

Au lieu de cela, vous devriez utiliser une valeur sentinelle indiquant "non donné" et remplacer par le mutable que vous souhaitez par défaut:

>>> def foo(x=None):
...     if x is None:
...         x = []
...     x.append(1)
...     print x
>>> foo()
[1]
>>> foo()
[1]

339



Envoyer des valeurs dans les fonctions du générateur. Par exemple ayant cette fonction:

def mygen():
    """Yield 5 until something else is passed back via send()"""
    a = 5
    while True:
        f = (yield a) #yield a and possibly get f in return
        if f is not None: 
            a = f  #store the new value

Vous pouvez:

>>> g = mygen()
>>> g.next()
5
>>> g.next()
5
>>> g.send(7)  #we send this back to the generator
7
>>> g.next() #now it will yield 7 until we send something else
7

317



Si vous n'aimez pas utiliser les espaces pour désigner les étendues, vous pouvez utiliser le style C {} en émettant:

from __future__ import braces

314



L'argument de l'étape dans les opérateurs de tranche. Par exemple:

a = [1,2,3,4,5]
>>> a[::2]  # iterate over the whole list in 2-increments
[1,3,5]

Le cas particulier x[::-1] est un idiome utile pour 'x inversé'.

>>> a[::-1]
[5,4,3,2,1]

305