web-dev-qa-db-fra.com

Fonctions cachées de Python

1420
jelovirt

Aplatissement de list avec sum() .

La fonction intégrée sum() peut être utilisée pour __add__list s, offrant ainsi un moyen pratique d'aplatir un list de list s:

_Python 2.7.1 (r271:86832, May 27 2011, 21:41:45) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> l = [[1, 2, 3], [4, 5], [6], [7, 8, 9]]
>>> sum(l, [])
[1, 2, 3, 4, 5, 6, 7, 8, 9]
_
9
Johnsyweb

Le modèle Borg

C'est un tueur de Alex Martelli . Toutes les instances de l'état Borg share. Cela supprime la nécessité d'utiliser le modèle singleton (les instances importent peu lorsque l'état est partagé) et est plutôt élégant (mais est plus compliqué avec de nouvelles classes).

La valeur de foo peut être réaffectée à tout moment et tout sera mis à jour, vous pouvez même réaffecter le dict entier. Borg est le nom parfait, lisez plus ici .

class Borg:
    __shared_state = {'foo': 'bar'}
    def __init__(self):
        self.__dict__ = self.__shared_state
    # rest of your class here

C'est parfait pour partager un eventlet.GreenPool afin de contrôler la concurrence.

9
cerberos

Attributs Top Secret

>>> class A(object): pass
>>> a = A()
>>> setattr(a, "can't touch this", 123)
>>> dir(a)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', "can't touch this"]
>>> a.can't touch this # duh
  File "<stdin>", line 1
    a.can't touch this
                     ^
SyntaxError: EOL while scanning string literal
>>> getattr(a, "can't touch this")
123
>>> setattr(a, "__class__.__name__", ":O")
>>> a.__class__.__name__
'A'
>>> getattr(a, "__class__.__name__")
':O'

Attributs ajoutés dynamiquement

Cela peut être utile si vous envisagez d'ajouter des attributs à vos classes simplement en les appelant. Cela peut être fait en remplaçant la fonction membre __getattribute__ qui est appelée lorsque l'opérande point est utilisé. Voyons un exemple de classe fictive:

_class Dummy(object):
    def __getattribute__(self, name):
        f = lambda: 'Hello with %s'%name
        return f
_

Lorsque vous instanciez un objet factice et effectuez un appel de méthode, vous obtenez les éléments suivants:

_>>> d = Dummy()
>>> d.b()
'Hello with b'
_

Enfin, vous pouvez même définir l'attribut sur votre classe afin qu'il puisse être défini de manière dynamique. Cela peut être utile si vous travaillez avec Python cadres Web et souhaitez effectuer des requêtes en analysant le nom de l'attribut.

J'ai un Gist sur github avec ce code simple et son équivalent sur Ruby créé par un ami.

Prends soin de toi!

9
FernandoEscher

namedtuple est un tuple

>>> node = namedtuple('node', "a b")
>>> node(1,2) + node(5,6)
(1, 2, 5, 6)
>>> (node(1,2), node(5,6))
(node(a=1, b=2), node(a=5, b=6))
>>> 

Quelques expériences supplémentaires pour répondre aux commentaires:

>>> from collections import namedtuple
>>> from operator import *
>>> mytuple = namedtuple('A', "a b")
>>> yourtuple = namedtuple('Z', "x y")
>>> mytuple(1,2) + yourtuple(5,6)
(1, 2, 5, 6)
>>> q = [mytuple(1,2), yourtuple(5,6)]
>>> q
[A(a=1, b=2), Z(x=5, y=6)]
>>> reduce(operator.__add__, q)
(1, 2, 5, 6)

Donc, namedtuple est un intéressant sous-type de Tuple.

9
Apalala

Création d'un dictionnaire de deux séquences contenant des données associées

In [15]: t1 = (1, 2, 3)

In [16]: t2 = (4, 5, 6)

In [17]: dict (Zip(t1,t2))
Out[17]: {1: 4, 2: 5, 3: 6}
9
Lakshman Prasad

threading.enumerate () donne accès à tous les objets Thread du système et sys._current_frames () renvoie les cadres de pile actuels de tous les threads du système. Combinez donc ces deux éléments pour obtenir le vidage de la pile de style Java:

def dumpstacks(signal, frame):
    id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
    code = []
    for threadId, stack in sys._current_frames().items():
        code.append("\n# Thread: %s(%d)" % (id2name[threadId], threadId))
        for filename, lineno, name, line in traceback.extract_stack(stack):
            code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
            if line:
                code.append("  %s" % (line.strip()))
    print "\n".join(code)

import signal
signal.signal(signal.SIGQUIT, dumpstacks)

Faites cela au début d’un programme multi-thread python et vous aurez accès à tout moment à l’état actuel des threads en envoyant un SIGQUIT. Vous pouvez également choisir signal.SIGUSR1 ou signal.SIGUSR2.

Voir

8
haridsv

pdb - Le Python Debugger

En tant que programmeur, l'une des premières choses dont vous avez besoin pour développer des programmes sérieux est un débogueur. Python possède un module intégré disponible en tant que module appelé pdb (pour "Python DeBugger", bien sûr!).

http://docs.python.org/library/pdb.html

8
Tom Viner

inspect le module est également une fonctionnalité intéressante.

7
Pratik Deoghare

Le rechargement des modules permet un style de "codage en direct". Mais les instances de classe ne sont pas mises à jour. Voici pourquoi et comment le contourner. Rappelez-vous, tout, oui, tout est un objet.

>>> from a_package import a_module
>>> cls = a_module.SomeClass
>>> obj = cls()
>>> obj.method()
(old method output)

Maintenant, vous modifiez la méthode dans a_module.py et souhaitez mettre à jour votre objet.

>>> reload(a_module)
>>> a_module.SomeClass is cls
False # Because it just got freshly created by reload.
>>> obj.method()
(old method output)

Voici un moyen de le mettre à jour (mais considérez-le avec des ciseaux):

>>> obj.__class__ is cls
True # it's the old class object
>>> obj.__class__ = a_module.SomeClass # pick up the new class
>>> obj.method()
(new method output)

Ceci est "en cours d'exécution avec des ciseaux" car l'état interne de l'objet peut être différent de celui attendu par la nouvelle classe. Cela fonctionne pour des cas vraiment simples, mais au-delà, pickle est votre ami. Il est toujours utile de comprendre pourquoi cela fonctionne, cependant.

7
Ken Arnold

Les opérateurs peuvent être appelés en tant que fonctions:

from operator import add
print reduce(add, [1,2,3,4,5,6])
7
Brendon Crawford

récursion infinie dans la liste

>>> a = [1,2]
>>> a.append(a)
>>> a
[1, 2, [...]]
>>> a[2]
[1, 2, [...]]
>>> a[2][2][2][2][2][2][2][2][2] == a
True
7
Elisha

... que dict.get() a un valeur par défaut de None, évitant ainsi KeyErrors:

In [1]: test = { 1 : 'a' }

In [2]: test[2]
---------------------------------------------------------------------------
<type 'exceptions.KeyError'>              Traceback (most recent call last)

&lt;ipython console&gt; in <module>()

<type 'exceptions.KeyError'>: 2

In [3]: test.get( 2 )

In [4]: test.get( 1 )
Out[4]: 'a'

In [5]: test.get( 2 ) == None
Out[5]: True

et même pour spécifier ceci "sur les lieux":

In [6]: test.get( 2, 'Some' ) == 'Some'
Out[6]: True

Et vous pouvez utiliser setdefault() pour avoir une valeur définie et renvoyée si elle n'existe pas:

>>> a = {}
>>> b = a.setdefault('foo', 'bar')
>>> a
{'foo': 'bar'}
>>> b
'bar
7
Steen

Les barres obliques inverses dans les chaînes brutes peuvent toujours échapper aux guillemets. Regarde ça:

>>> print repr(r"aaa\"bbb")
'aaa\\"bbb'

Notez que les barres obliques inverses et les guillemets doubles sont présents dans la dernière chaîne.

Par conséquent, vous ne pouvez pas terminer une chaîne brute avec une barre oblique inverse:

>>> print repr(r"C:\")
SyntaxError: EOL while scanning string literal
>>> print repr(r"C:\"")
'C:\\"'

Cela est dû au fait que les chaînes brutes ont été implémentées pour faciliter l'écriture d'expressions régulières et non pour écrire les chemins Windows. Lisez une longue discussion à ce sujet sur le site Gotcha - barres obliques inverses dans les noms de fichiers Windows .

7
Denilson Sá Maia

Les objets de petit intères (-5 .. 256) n'ont jamais été créés deux fois:


>>> a1 = -5; b1 = 256
>>> a2 = -5; b2 = 256
>>> id(a1) == id(a2), id(b1) == id(b2)
(True, True)
>>>
>>> c1 = -6; d1 = 257
>>> c2 = -6; d2 = 257
>>> id(c1) == id(c2), id(d1) == id(d2)
(False, False)
>>>

Edition: Les objets de liste ne sont jamais détruits (uniquement les objets dans les listes). Python possède un tableau dans lequel il conserve jusqu'à 80 listes vides. Lorsque vous détruisez un objet de liste - python le place dans ce tableau et lorsque vous créez une nouvelle liste - python, la dernière liste insérée provient de ce tableau:


>>> a = [1,2,3]; a_id = id(a)
>>> b = [1,2,3]; b_id = id(b)
>>> del a; del b
>>> c = [1,2,3]; id(c) == b_id
True
>>> d = [1,2,3]; id(d) == a_id
True
>>>
6
Mykola Kharechko

Tranches en lvalues. Ce tamis d'Eratosthenes produit une liste qui a le nombre premier ou 0. Les éléments sont supprimés avec l'attribution de tranche dans la boucle.

def eras(n):
    last = n + 1
    sieve = [0,0] + list(range(2, last))
    sqn = int(round(n ** 0.5))
    it = (i for i in xrange(2, sqn + 1) if sieve[i])
    for i in it:
        sieve[i*i:last:i] = [0] * (n//i - i + 1)
    return filter(None, sieve)

Pour travailler, la tranche de gauche doit se voir attribuer une liste de droite de la même longueur.

6
hughdbrown

Arrondir les entiers: Python a la fonction round, qui renvoie les nombres de type double:

 >>> print round(1123.456789, 4)
1123.4568
 >>> print round(1123.456789, 2)
1123.46
 >>> print round(1123.456789, 0)
1123.0

Cette fonction a une merveilleuse propriété magique:

 >>> print round(1123.456789, -1)
1120.0
 >>> print round(1123.456789, -2)
1100.0

Si vous avez besoin d'un entier, utilisez int pour convertir le type:

 >>> print int(round(1123.456789, -2))
1100
 >>> print int(round(8359980, -2))
8360000

Merci Gregor .

6
yoav.aviram

Manipulation de la limite de récursivité

Obtenir ou définir la profondeur maximale de récursivité avec sys.getrecursionlimit () & sys.setrecursionlimit ().

Nous pouvons le limiter pour éviter un débordement de pile causé par une récursion infinie.

6
grayger

Vous pouvez remplacer la mro d'une classe avec une métaclasse

>>> class A(object):
...     def a_method(self):
...         print("A")
... 
>>> class B(object):
...     def b_method(self):
...         print("B")
... 
>>> class MROMagicMeta(type):
...     def mro(cls):
...         return (cls, B, object)
... 
>>> class C(A, metaclass=MROMagicMeta):
...     def c_method(self):
...         print("C")
... 
>>> cls = C()
>>> cls.c_method()
C
>>> cls.a_method()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute 'a_method'
>>> cls.b_method()
B
>>> type(cls).__bases__
(<class '__main__.A'>,)
>>> type(cls).__mro__
(<class '__main__.C'>, <class '__main__.B'>, <class 'object'>)

C'est probablement caché pour une bonne raison. :)

6
Benjamin Peterson

Possibilité de remplacer même des éléments tels que la suppression de fichiers, l'ouverture de fichiers, etc. - manipulation directe de la bibliothèque de langues. C'est un avantage énorme quand test. Vous n'avez pas à tout emballer dans des conteneurs compliqués. Remplacez simplement une fonction/méthode et partez. Ceci est également appelé singe-patcher.

6
Paweł Hajdan

tranches et mutabilité

Copier des listes

>>> x = [1,2,3]
>>> y = x[:]
>>> y.pop()
3
>>> y
[1, 2]
>>> x
[1, 2, 3]

Remplacement des listes

>>> x = [1,2,3]
>>> y = x
>>> y[:] = [4,5,6]
>>> x
[4, 5, 6]
6
Daniel Hepper

Nouvelle liaison des paramètres de fonction imbriquée

def create_printers(n):
    for i in xrange(n):
        def printer(i=i): # Doesn't work without the i=i
            print i
        yield printer
6
ironfroggy

Python 2.x ignore les virgules s'il se trouve après le dernier élément de la séquence:

>>> a_Tuple_for_instance = (0,1,2,3,)
>>> another_Tuple = (0,1,2,3)
>>> a_Tuple_for_instance == another_Tuple
True

Une virgule finale fait en sorte qu'un élément entre parenthèses soit traité comme une séquence:

>>> a_Tuple_with_one_element = (8,)
6
Martin

Les méthodes ou fonctions intégrées n'implémentent pas le protocole de descripteur, ce qui rend impossible la réalisation de tâches comme celle-ci:

>>> class C(object):
...  id = id
... 
>>> C().id()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: id() takes exactly one argument (0 given)

Cependant, vous pouvez créer un petit descripteur de liaison qui rend cela possible:

>>> from types import MethodType
>>> class bind(object):
...  def __init__(self, callable):
...   self.callable = callable
...  def __get__(self, obj, type=None):
...   if obj is None:
...    return self
...   return MethodType(self.callable, obj, type)
... 
>>> class C(object):
...  id = bind(id)
... 
>>> C().id()
7414064
6
Armin Ronacher

Vous pouvez décorer des fonctions avec des classes - en remplaçant la fonction par une instance de classe:

class countCalls(object):
    """ decorator replaces a function with a "countCalls" instance
    which behaves like the original function, but keeps track of calls

    >>> @countCalls
    ... def doNothing():
    ...     pass
    >>> doNothing()
    >>> doNothing()
    >>> print doNothing.timesCalled
    2
    """
    def __init__ (self, functionToTrack):
        self.functionToTrack = functionToTrack
        self.timesCalled = 0
    def __call__ (self, *args, **kwargs):
        self.timesCalled += 1
        return self.functionToTrack(*args, **kwargs)
6
Markus

Je ne sais pas où (ou si) cela se trouve dans la documentation Python, mais pour python 2.x (au moins 2.5 et 2.6, ce que je viens d'essayer), le print déclaration peut être appelée avec parenthenses. Cela peut être utile si vous voulez pouvoir facilement porter du code Python 2. 2.x sur Python 3.x.

Exemple: print('We want Moshiach Now') devrait imprimer We want Moshiach Now travailler en python 2.5, 2.6 et 3.x.

De même, l'opérateur not peut être appelé avec des parenthenses dans Python 2 et 3: not False et not(False) doivent tous deux renvoyer True.

Les parenthèses peuvent également fonctionner avec d'autres instructions et opérateurs.

EDIT: Ce n'est PAS une bonne idée de placer des parenthenses autour des opérateurs not (et probablement de tout autre opérateur), car cela peut créer des situations surprenantes, comme ça (c'est parce que les parenthenses sont vraiment autour du 1):

>>> (not 1) == 9
False

>>> not(1) == 9
True

Cela peut aussi fonctionner, pour certaines valeurs (je pense que ce n'est pas un nom d'identifiant valide), comme ceci: not'val' doit renvoyer False, et print'We want Moshiach Now' devrait renvoyer We want Moshiach Now. (mais not552 lèverait un NameError puisqu'il s'agit d'un nom d'identifiant valide).

5
Abbafei

Dict Compréhensions

>>> {i: i**2 for i in range(5)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

documentation Python

Entrée Wikipedia

5
Justin

Trop paresseux pour initialiser tous les champs d'un dictionnaire? Aucun problème:

Dans Python> 2.3:

from collections import defaultdict

Dans Python <= 2.3:

def defaultdict(type_):
    class Dict(dict):
        def __getitem__(self, key):
            return self.setdefault(key, type_())
    return Dict()

Dans n'importe quelle version:

d = defaultdict(list)
for stuff in lots_of_stuff:
     d[stuff.name].append(stuff)

UPDATE:

Merci Ken Arnold . J'ai réimplémenté une version plus sophistiquée de defaultdict. Il devrait se comporter exactement comme celui de la bibliothèque standard .

def defaultdict(default_factory, *args, **kw):                              

    class defaultdict(dict):

        def __missing__(self, key):
            if default_factory is None:
                raise KeyError(key)
            return self.setdefault(key, default_factory())

        def __getitem__(self, key):
            try:
                return dict.__getitem__(self, key)
            except KeyError:
                return self.__missing__(key)

    return defaultdict(*args, **kw)
5
pi.

Objets Monkeypatching

Chaque objet de Python a un membre __dict__, qui stocke les attributs de l'objet. Donc, vous pouvez faire quelque chose comme ça:

class Foo(object):
    def __init__(self, arg1, arg2, **kwargs):
        #do stuff with arg1 and arg2
        self.__dict__.update(kwargs)

f = Foo('arg1', 'arg2', bar=20, baz=10)
#now f is a Foo object with two extra attributes

Cela pourrait être exploité pour ajouter à la fois des attributs et des fonctions aux objets. Cela peut également être exploité pour créer un type struct rapide.

class struct(object):
    def __init__(**kwargs):
       self.__dict__.update(kwargs)

s = struct(foo=10, bar=11, baz="i'm a string!')
5
Chinmay Kanchi

Outil d'analyse comparative intégré simple

La bibliothèque standard Python est livrée avec un module d’analyse comparative très simple à utiliser appelé "timeit". Vous pouvez même l'utiliser à partir de la ligne de commande pour voir laquelle de plusieurs constructions de langage est la plus rapide.

Par exemple.,

% python -m timeit 'r = range(0, 1000)' 'for i in r: pass'
10000 loops, best of 3: 48.4 usec per loop

% python -m timeit 'r = xrange(0, 1000)' 'for i in r: pass'
10000 loops, best of 3: 37.4 usec per loop
5
Douglas

Set Compréhensions

>>> {i**2 for i in range(5)}                                                       
set([0, 1, 4, 16, 9])

documentation Python

Entrée Wikipedia

5
Justin

En plus de ce qui a été mentionné précédemment par haridsv :

>>> foo = bar = baz = 1
>>> foo, bar, baz
(1, 1, 1)

il est également possible de faire ceci:

>>> foo, bar, baz = 1, 2, 3
>>> foo, bar, baz
(1, 2, 3)
5
armandino

Liste des compréhensions

liste des compréhensions

Comparez le plus traditionnel (sans compréhension de liste):

foo = []
for x in xrange(10):
  if x % 2 == 0:
     foo.append(x)

à:

foo = [x for x in xrange(10) if x % 2 == 0]
5
Oko

Voici 2 oeufs de Pâques:


Un dans python lui-même:

>>> import __hello__
Hello world...

Et un autre dans le module Werkzeug, qui est un peu compliqué à révéler, le voici:

En regardant le code source de Werkzeug, dans werkzeug/__init__.py, une ligne devrait attirer votre attention:

'werkzeug._internal':   ['_easteregg']

Si vous êtes un peu curieux, vous devriez jeter un coup d'œil à la werkzeug/_internal.py. Vous y trouverez une fonction _easteregg() qui prend une application wsgi en argument, elle contient également des bases64. données codées et 2 fonctions imbriquées, qui semblent faire quelque chose de spécial si un argument nommé macgybarchakku est trouvé dans la chaîne de requête.

Donc, pour révéler cet oeuf de Pâques, il semble que vous ayez besoin d'envelopper une application dans la fonction _easteregg(), allons:

from werkzeug import Request, Response, run_simple
from werkzeug import _easteregg

@Request.application
def application(request):
    return Response('Hello World!')

run_simple('localhost', 8080, _easteregg(application))

Maintenant, si vous exécutez l'application et visitez http: // localhost: 8080 /? Macgybarchakk , vous devriez voir l'oeuf de Pâques.

5
mdeous

Si vous utilisez des descripteurs sur vos classes, Python contourne complètement __dict__ pour cette clé, ce qui en fait un endroit agréable pour stocker ces valeurs:

>>> class User(object):
...  def _get_username(self):
...   return self.__dict__['username']
...  def _set_username(self, value):
...   print 'username set'
...   self.__dict__['username'] = value
...  username = property(_get_username, _set_username)
...  del _get_username, _set_username
... 
>>> u = User()
>>> u.username = "foo"
username set
>>> u.__dict__
{'username': 'foo'}

Cela aide à garder dir() clean.

5
Armin Ronacher

L'idiome Pythonic x = ... if ... else ... est de loin supérieur à x = ... and ... or ... et voici pourquoi:

Bien que la déclaration

x = 3 if (y == 1) else 2

Est équivalent à

x = y == 1 and 3 or 2

si vous utilisez le langage x = ... and ... or ..., vous risquez un jour d'être piqué par cette situation délicate:

x = 0 if True else 1    # sets x equal to 0

et n'est donc pas équivalent à

x = True and 0 or 1   # sets x equal to 1

Pour plus d'informations sur la manière appropriée de procéder, voir Fonctionnalités cachées de Python .

5
Amol
5
Gurch

Exposition de tampons mutables

Utilisation du Python protocole de tampon pour exposer les tampons modifiables orientés octets dans Python (2.5/2.6) .

(Désolé, pas de code ici. Nécessite l'utilisation de l'API C de bas niveau ou du module d'adaptateur existant).

5
user166390

getattr prend un troisième paramètre

getattr(obj, attribute_name, default) est comme:

try:
    return obj.attribute
except AttributeError:
    return default

sauf que attribute_name peut être n'importe quelle chaîne.

Cela peut être vraiment utile pour frappe de canard . Peut-être que vous avez quelque chose comme:

class MyThing:
    pass
class MyOtherThing:
    pass
if isinstance(obj, (MyThing, MyOtherThing)):
    process(obj)

(btw, isinstance(obj, (a,b)) signifie isinstance(obj, a) or isinstance(obj, b).)

Lorsque vous créez un nouveau type d’objet, vous devez l’ajouter à ce tuple où qu’il se produise. (Cette construction pose également des problèmes lors du rechargement de modules ou de l'importation du même fichier sous deux noms. Cela se produit plus que ce que les gens aiment bien admettre.) Mais vous pourriez plutôt dire:

class MyThing:
    processable = True
class MyOtherThing:
    processable = True
if getattr(obj, 'processable', False):
    process(obj)

Ajoutez l'héritage et cela s'améliore encore: tous vos exemples d'objets pouvant être traités peuvent hériter de

class Processable:
    processable = True

mais vous n'avez pas à convaincre tout le monde d'hériter de votre classe de base, il vous suffit de définir un attribut.

5
Ken Arnold

__ getattr __ ()

getattr est un moyen vraiment agréable de créer des classes génériques, ce qui est particulièrement utile si vous écrivez une API. Par exemple, dans FogBugz Python API , getattr permet de transmettre de manière transparente les appels de méthode au service Web:

class FogBugz:
    ...

    def __getattr__(self, name):
        # Let's leave the private stuff to Python
        if name.startswith("__"):
            raise AttributeError("No such attribute '%s'" % name)

        if not self.__handlerCache.has_key(name):
            def handler(**kwargs):
                return self.__makerequest(name, **kwargs)
            self.__handlerCache[name] = handler
        return self.__handlerCache[name]
    ...

Lorsque quelqu'un appelle FogBugz.search(q='bug'), il n'appelle pas une méthode search. Au lieu de cela, getattr gère l'appel en créant une nouvelle fonction qui englobe la méthode makerequest, qui crée la demande HTTP appropriée à l'API Web. Toutes les erreurs seront envoyées par le service Web et renvoyées à l'utilisateur.

5
tghw

La première classe de tout ("tout est objet") et le chaos que cela peut causer.

>>> x = 5
>>> y = 10
>>> 
>>> def sq(x):
...   return x * x
... 
>>> def plus(x):
...   return x + x
... 
>>> (sq,plus)[y>x](y)
20

La dernière ligne crée un tuple contenant les deux fonctions, puis évalue y> x (True) et l’utilise comme un index du tuple (en le convertissant en un entier int, 1), puis appelle cette fonction avec le paramètre y et affiche le résultat.

Si vous renvoyez un objet avec un index (une liste, par exemple), vous pouvez ajouter des crochets supplémentaires à la fin du message. si le contenu était appelable, plus de parenthèses, etc. Pour plus de perversion, utilisez le résultat du code comme ceci comme expression dans un autre exemple (c'est-à-dire remplacez y> x par ce code):

(sq,plus)[y>x](y)[4](x)

Cela présente deux facettes de Python - la philosophie du "tout est un objet" poussée à l'extrême, et les méthodes par lesquelles une utilisation incorrecte ou mal conçue de la syntaxe du langage peut conduire à un code spaghetti complètement illisible et non maintenable cela correspond à une seule expression.

4
Dan Udey

Tuple décompactant pour les boucles, les compréhensions de liste et les expressions de générateur:

>>> l=[(1,2),(3,4)]
>>> [a+b for a,b in l ] 
[3,7]

Utile dans cet idiome pour itérer des paires (clé, données) dans des dictionnaires:

d = { 'x':'y', 'f':'e'}
for name, value in d.items():  # one can also use iteritems()
   print "name:%s, value:%s" % (name,value)

impressions:

name:x, value:y
name:f, value:e
4
Rafał Dowgird

Avec un volume de travail minime, le module de filetage devient incroyablement facile à utiliser. Ce décorateur modifie une fonction afin qu'elle s'exécute dans son propre thread, renvoyant une instance de classe d'espace réservé au lieu de son résultat habituel. Vous pouvez rechercher la réponse en cochant placeolder.result ou l'attendre en appelant placeholder.awaitResult ().

def threadify(function):
    """
    exceptionally simple threading decorator. Just:
    >>> @threadify
    ... def longOperation(result):
    ...     time.sleep(3)
    ...     return result
    >>> A= longOperation("A has finished")
    >>> B= longOperation("B has finished")

    A doesn't have a result yet:
    >>> print A.result
    None

    until we wait for it:
    >>> print A.awaitResult()
    A has finished

    we could also wait manually - half a second more should be enough for B:
    >>> time.sleep(0.5); print B.result
    B has finished
    """
    class thr (threading.Thread,object):
        def __init__(self, *args, **kwargs):
            threading.Thread.__init__ ( self )  
            self.args, self.kwargs = args, kwargs
            self.result = None
            self.start()
        def awaitResult(self):
            self.join()
            return self.result        
        def run(self):
            self.result=function(*self.args, **self.kwargs)
    return thr
4
Markus

Python a des exceptions pour des choses très inattendues:

Importations

Cela vous permet d'importer une alternative s'il manque une lib

try:
    import json
except ImportError:
    import simplejson as json

Itération

Les boucles for le font en interne et attrapent StopIteration:

iter([]).next()
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    iter(a).next()
StopIteration

Assertion

>>> try:
...     assert []
... except AssertionError:
...     print "This list should not be empty"
This list should not be empty

Bien que cela soit plus détaillé pour une vérification, plusieurs vérifications combinant des exceptions et des opérateurs booléens avec le même message d'erreur peuvent être abrégées de cette façon.

4
e-satis

Il n'y a pas de secrets dans Python;)

4
Juanjo Conti

Combinez le déballage avec la fonction d'impression:

# in 2.6 <= python < 3.0, 3.0 + the print function is native
from __future__ import print_function 

mylist = ['foo', 'bar', 'some other value', 1,2,3,4]  
print(*mylist)
4
Wayne Werner

Méthode de remplacement pour l'instance d'objet

Vous pouvez remplacer les méthodes d'instances d'objet déjà créées. Il vous permet de créer une instance d'objet avec différentes fonctionnalités (exceptionnelles):

>>> class C(object):
...     def fun(self):
...         print "C.a", self
...
>>> inst = C()
>>> inst.fun()  # C.a method is executed
C.a <__main__.C object at 0x00AE74D0>
>>> instancemethod = type(C.fun)
>>>
>>> def fun2(self):
...     print "fun2", self
...
>>> inst.fun = instancemethod(fun2, inst, C)  # Now we are replace C.a by fun2
>>> inst.fun()  # ... and fun2 is executed
fun2 <__main__.C object at 0x00AE74D0>

Comme nous pouvons, C.a a été remplacé par fun2() dans inst instance (self n'a pas changé).

Alternativement, nous pouvons utiliser le module new, mais il est déprécié depuis Python 2.6:

>>> def fun3(self):
...     print "fun3", self
...
>>> import new
>>> inst.fun = new.instancemethod(fun3, inst, C)
>>> inst.fun()
fun3 <__main__.C object at 0x00AE74D0>

Node: Cette solution ne doit pas être utilisée comme remplacement général du mécanisme d'héritage! Mais cela peut être très pratique dans certaines situations spécifiques (débogage, moquage).

Attention: Cette solution ne fonctionnera pas pour les types intégrés ni pour les nouvelles classes de style utilisant des slots.

4
Tupteq

Profitant de la nature dynamique de python pour avoir une configuration de fichiers d’applications dans la syntaxe python. Par exemple, si vous aviez les éléments suivants dans un fichier de configuration:

{
  "name1": "value1",
  "name2": "value2"
}

Ensuite, vous pourriez trivialement le lire comme:

config = eval(open("filename").read())
4
pixelbeat

Accéder aux éléments du dictionnaire en tant qu'attributs (propriétés). donc si a1 = AttrDict () a la clé 'nom' -> au lieu de a1 ['nom'], nous pouvons facilement accéder à l'attribut name de a1 en utilisant -> a1.name


class AttrDict(dict):

    def __getattr__(self, name):
        if name in self:
            return self[name]
        raise AttributeError('%s not found' % name)

    def __setattr__(self, name, value):
        self[name] = value

    def __delattr__(self, name):
        del self[name]

person = AttrDict({'name': 'John Doe', 'age': 66})
print person['name']
print person.name

person.name = 'Frodo G'
print person.name

del person.age

print person
4
amix

Méthodes spéciales

pouvoir absolu!

4
cleg

Identifiant Unicode en Python3:

>>> 'Unicode字符_تكوين_Variable'.isidentifier()
True
>>> Unicode字符_تكوين_Variable='Python3 rules!'
>>> Unicode字符_تكوين_Variable
'Python3 rules!'
4
Kabie

n module exporte TOUT dans son espace de noms

Y compris les noms importés d'autres modules!

# this is "answer42.py"
from operator import *
from inspect  import *

Maintenant, testez ce qui est importable depuis le module.

>>> import answer42
>>> answer42.__dict__.keys()
['gt', 'imul', 'ge', 'setslice', 'ArgInfo', 'getfile', 'isCallable', 'getsourcelines', 'CO_OPTIMIZED', 'le', 're', 'isgenerator', 'ArgSpec', 'imp', 'lt', 'delslice', 'BlockFinder', 'getargspec', 'currentframe', 'CO_NOFREE', 'namedtuple', 'rshift', 'string', 'getframeinfo', '__file__', 'strseq', 'iconcat', 'getmro', 'mod', 'getcallargs', 'isub', 'getouterframes', 'isdatadescriptor', 'modulesbyfile', 'setitem', 'truth', 'Attribute', 'div', 'CO_NESTED', 'ixor', 'getargvalues', 'ismemberdescriptor', 'getsource', 'isMappingType', 'eq', 'index', 'xor', 'sub', 'getcomments', 'neg', 'getslice', 'isframe', '__builtins__', 'abs', 'getmembers', 'mul', 'getclasstree', 'irepeat', 'is_', 'getitem', 'indexOf', 'Traceback', 'findsource', 'ModuleInfo', 'ipow', 'TPFLAGS_IS_ABSTRACT', 'or_', 'joinseq', 'is_not', 'itruediv', 'getsourcefile', 'dis', 'os', 'iand', 'countOf', 'getinnerframes', 'pow', 'pos', 'and_', 'lshift', '__name__', 'sequenceIncludes', 'isabstract', 'isbuiltin', 'invert', 'contains', 'add', 'isSequenceType', 'irshift', 'types', 'tokenize', 'isfunction', 'not_', 'istraceback', 'getmoduleinfo', 'isgeneratorfunction', 'getargs', 'CO_GENERATOR', 'cleandoc', 'classify_class_attrs', 'EndOfBlock', 'walktree', '__doc__', 'getmodule', 'isNumberType', 'ilshift', 'ismethod', 'ifloordiv', 'formatargvalues', 'indentsize', 'getmodulename', 'inv', 'Arguments', 'iscode', 'CO_NEWLOCALS', 'formatargspec', 'iadd', 'getlineno', 'imod', 'CO_VARKEYWORDS', 'ne', 'idiv', '__package__', 'CO_VARARGS', 'attrgetter', 'methodcaller', 'truediv', 'repeat', 'trace', 'isclass', 'ior', 'ismethoddescriptor', 'sys', 'isroutine', 'delitem', 'stack', 'concat', 'getdoc', 'getabsfile', 'ismodule', 'linecache', 'floordiv', 'isgetsetdescriptor', 'itemgetter', 'getblock']
>>> from answer42 import getmembers
>>> getmembers
<function getmembers at 0xb74b2924>
>>> 

C'est une bonne raison de ne pas utiliser from x import * et de définir __all__ =.

4
Apalala

insérer vs ajouter

pas une fonctionnalité, mais peut être intéressant

supposons que vous souhaitiez insérer des données dans une liste, puis l'inverser. la chose la plus facile est

count = 10 ** 5
nums = []
for x in range(count):
    nums.append(x)
nums.reverse()

alors vous pensez: que diriez-vous d'insérer les nombres depuis le début, à la place? alors:

count = 10 ** 5 
nums = [] 
for x in range(count):
    nums.insert(0, x)

mais il s'avère être 100 fois plus lent! si nous fixons count = 10 ** 6, ce sera 1 000 fois plus lent; c'est parce que insert est O (n ^ 2), alors que append est O (n).

la raison de cette différence est que insert doit déplacer chaque élément d'une liste chaque fois qu'il est appelé; simplement ajouter à la fin de la liste que des éléments

4
Ant

Vous pouvez affecter plusieurs variables à la même valeur

>>> foo = bar = baz = 1
>>> foo, bar, baz
(1, 1, 1)

Utile pour initialiser plusieurs variables sur Aucune, de manière compacte.

4
haridsv

Simulation de l'opérateur tertiaire à l'aide de et et ou.

et et ou les opérateurs dans python renvoient les objets eux-mêmes plutôt que des booléens. Ainsi:

In [18]: a = True

In [19]: a and 3 or 4
Out[19]: 3

In [20]: a = False

In [21]: a and 3 or 4
Out[21]: 4

Cependant, Py 2.5 semble avoir ajouté un opérateur tertiaire explicite

    In [22]: a = 5 if True else '6'

    In [23]: a
    Out[23]: 5

Eh bien, cela fonctionne si vous êtes sûr que votre vraie clause n’est pas évaluée à False. exemple:

>>> def foo(): 
...     print "foo"
...     return 0
...
>>> def bar(): 
...     print "bar"
...     return 1
...
>>> 1 and foo() or bar()
foo
bar
1

Pour bien faire les choses, il vous faut juste un peu plus:

>>> (1 and [foo()] or [bar()])[0]
foo
0

Cependant, ce n'est pas aussi joli. si votre version de python le prend en charge, utilisez l'opérateur conditionnel.

>>> foo() if True or bar()
foo
0
3
Lakshman Prasad

Imprimer des chaînes multilignes, une page à la fois

Fonctionnalité pas vraiment utile cachée dans la classe site._Printer dont l'objet license est une instance. Ce dernier, lorsqu'il est appelé, imprime la licence Python. On peut créer un autre objet du même type en passant une chaîne - par ex. le contenu d'un fichier - comme second argument, et appelez-le:

type(license)(0,open('textfile.txt').read(),0)()

Cela imprimerait le contenu du fichier divisé en un certain nombre de lignes à la fois:

...
file row 21
file row 22
file row 23

Hit Return for more, or q (and Return) to quit:
3
etuardu

Tout est dynamique

"Il n'y a pas de temps de compilation". Tout dans Python correspond à l'exécution. Un module est "défini" en exécutant la source du module de haut en bas, exactement comme un script, et l'espace de nom résultant est l'espace attribut du module. De même, une classe est "définie" en exécutant le corps de la classe de haut en bas, et l'espace de noms résultant est l'espace attribut de la classe. Un corps de classe peut contenir du code complètement arbitraire, y compris des instructions d'importation, des boucles et d'autres instructions de classe. Créer une classe, une fonction ou même un module "dynamiquement", comme on le demande parfois, n'est pas difficile; en fait, il est impossible d'éviter, puisque tout est "dynamique".

3
Thomas Wouters

Python a des variables "privées"

Les variables qui commencent, mais ne se terminent pas, par un double soulignement deviennent privées, et pas seulement par convention. En réalité, __var se transforme en _Classname__var, où Classname est la classe dans laquelle la variable a été créée. Ils ne sont pas hérités et ne peuvent pas être annulés.


>>> class A:
...     def __init__(self):
...             self.__var = 5
...     def getvar(self):
...             return self.__var
... 
>>> a = A()
>>> a.__var
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: A instance has no attribute '__var'
>>> a.getvar()
5
>>> dir(a)
['_A__var', '__doc__', '__init__', '__module__', 'getvar']
>>>
3
Ivan P

Le fait que TOUT soit un objet, et en tant que tel, est extensible. Je peux ajouter des variables de membre en tant que métadonnées à une fonction que je définis:

>>> def addInts(x,y): 
...    return x + y
>>> addInts.params = ['integer','integer']
>>> addInts.returnType = 'integer'

Cela peut être très utile pour écrire des tests unitaires dynamiques, par exemple.

3
Greg

bien que peu pythonique, vous pouvez écrire dans un fichier avec print

print>>outFile, 'I am Being Written'

Explication :

Ce formulaire est parfois appelé "chevron print". Dans ce formulaire, la première expression après le >> doit correspondre à un objet "semblable à un fichier", en particulier un objet ayant la méthode write() décrite ci-dessus. Avec cette forme étendue, les expressions suivantes sont imprimées dans cet objet fichier. Si la première expression est évaluée à None, alors sys.stdout est utilisé comme fichier de sortie.

3
matchew

Objets en contexte booléen

Les n-uplets, les listes, les dict, les chaînes et bien d'autres objets vides sont équivalents à False dans un contexte booléen (et non-vides sont équivalents à True).

empty_Tuple = ()
empty_list = []
empty_dict = {}
empty_string = ''
empty_set = set()
if empty_Tuple or empty_list or empty_dict or empty_string or empty_set:
  print 'Never happens!'

Cela permet aux opérations logiques de renvoyer l'un de ses opérandes au lieu de True/False, ce qui est utile dans certaines situations:

s = t or "Default value" # s will be assigned "Default value"
                         # if t is false/empty/none
3
Constantin

Si vous avez renommé une classe dans votre application dans laquelle vous chargez des fichiers sauvegardés par l'utilisateur via Pickle et qu'une des classes renommées est stockée dans l'ancienne sauvegarde de l'utilisateur, vous ne pourrez pas charger ce fichier.

Cependant, ajoutez simplement une référence à la définition de votre classe et tout va bien:

par exemple, avant:

class Bleh:
    pass

maintenant,

class Blah:
    pass

le fichier sauvegardé de votre utilisateur contient donc une référence à Bleh, qui n'existe pas en raison du renommage. Le correctif?

Bleh = Blah

facile!

3
Steven Sproat

Support fonctionnel.

Générateurs et expressions de générateur, en particulier.

Ruby a refait ce courant, mais Python peut le faire aussi bien. Pas aussi omniprésent dans les bibliothèques que dans Ruby, ce qui est dommage, mais j'aime mieux la syntaxe, c'est plus simple.

Parce qu'ils ne sont pas aussi omniprésents, je ne vois pas autant d'exemples de leur utilité, mais ils m'ont permis d'écrire du code plus propre et plus efficace.

3
Karl Anderson

Méthodes privées et dissimulation de données (encapsulation)

Il existe un idiome commun dans Python consistant à désigner des méthodes et d'autres membres de la classe qui ne sont pas destinés à faire partie de l'API externe de la classe en leur attribuant des noms commençant par des traits de soulignement. C'est pratique et fonctionne très bien dans la pratique, mais cela donne une fausse impression que Python ne supporte pas l'encapsulation vraie de code privé et/ou de données. En fait, Python vous donne automatiquement fermetures lexicales , ce qui facilite grandement l'encapsulation des données de manière beaucoup plus efficace lorsque la situation le justifie vraiment. Voici un exemple artificiel d'une classe qui utilise cette technique:

class MyClass(object):
  def __init__(self):

    privateData = {}

    self.publicData = 123

    def privateMethod(k):
      print privateData[k] + self.publicData

    def privilegedMethod():
      privateData['foo'] = "hello "
      privateMethod('foo')

    self.privilegedMethod = privilegedMethod

  def publicMethod(self):
    print self.publicData

Et voici un exemple artificiel de son utilisation:

>>> obj = MyClass()
>>> obj.publicMethod()
123
>>> obj.publicData = 'World'
>>> obj.publicMethod()
World
>>> obj.privilegedMethod()
hello World
>>> obj.privateMethod()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'privateMethod'
>>> obj.privateData
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'privateData'

La clé est que privateMethod et privateData ne sont pas du tout des attributs d'obj. Ils ne peuvent donc pas être consultés de l'extérieur et ne sont pas affichés dans dir() ou similaire. Ce sont des variables locales dans le constructeur, complètement inaccessibles en dehors de __init__. Cependant, en raison de la magie des fermetures, il s’agit en réalité de variables par instance ayant la même durée de vie que l’objet auquel elles sont associées, même s’il n’est pas possible d’y accéder de l’extérieur sauf (dans cet exemple) en invoquant privilegedMethod. Souvent, ce type d’encapsulation très stricte est excessif, mais il peut parfois être très utile de garder une API ou un espace de noms parfaitement propre.

Dans Python 2.x, le seul moyen d'avoir un état privé mutable est d'utiliser un objet mutable (tel que dict dans cet exemple). Beaucoup de gens ont remarqué à quel point cela pouvait être agaçant. Python 3.x supprimera cette restriction en introduisant le mot clé nonlocal décrit dans PEP 3104 .

3
zaphod

Un moyen simple de tester si une clé est dans un dict:

>>> 'key' in { 'key' : 1 }
True

>>> d = dict(key=1, key2=2)
>>> if 'key' in d:
...     print 'Yup'
... 
Yup
3
six8
** Using sets to reference contents in sets of frozensets**

Comme vous le savez probablement, les ensembles sont modifiables et ne peuvent donc pas être utilisés. Il est donc nécessaire d’utiliser frozensets si vous souhaitez créer un ensemble d’ensembles (ou d’utiliser des ensembles comme clés de dictionnaire):

>>> fabc = frozenset('abc')
>>> fxyz = frozenset('xyz')
>>> mset = set((fabc, fxyz))
>>> mset
{frozenset({'a', 'c', 'b'}), frozenset({'y', 'x', 'z'})}

Cependant, il est possible de tester l'adhésion et de supprimer/supprimer des membres en utilisant uniquement des ensembles ordinaires:

>>> abc = set('abc')
>>> abc in mset
True
>>> mset.remove(abc)
>>> mset
{frozenset({'y', 'x', 'z'})}

Pour citer les docs Python Standard Library:

Notez que l'argument elem des méthodes __contains__(), remove() et discard() peut être un ensemble. Pour prendre en charge la recherche d'un groupe de frozens équivalent, le jeu elem est muté temporairement pendant la recherche, puis restauré. Au cours de la recherche, l'ensemble elem ne doit pas être lu ou muté car il n'a pas de valeur explicite.

Malheureusement, et peut-être étonnamment, il n'en va pas de même pour les dictionnaires:

>>> mdict = {fabc:1, fxyz:2}
>>> fabc in mdict
True
>>> abc in mdict
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: unhashable type: 'set'
3
Don O'Donnell

La fonction intégrée getattr:

>>> class C():
    def getMontys(self):
        self.montys = ['Cleese','Palin','Idle','Gilliam','Jones','Chapman']
        return self.montys


>>> c = C()
>>> getattr(c,'getMontys')()
['Cleese', 'Palin', 'Idle', 'Gilliam', 'Jones', 'Chapman']
>>> 

Utile si vous souhaitez répartir une fonction en fonction du contexte. Voir des exemples dans Plonger dans Python ( Here )

2
Busted Keaton

En ce qui concerne l'implémentation par Nick Johnson de Property class (juste une démonstration de descripteurs, bien sûr, pas un remplaçant pour le prédéfini), j'inclurais un séparateur qui soulève un AttributeError:

 class Property (objet): 
 def __init __ (self, fget): 
 self.fget = fget 
 
 def __get __ (self, obj , tapez): 
 si obj est None: 
 retourner soi-même 
 retourner soi-même.fget (obj) 
 
 def __set __ (soi, obj, valeur): 
 raise AttributeError, 'Attribut en lecture seule' 

L'inclusion du setter en fait un descripteur de données par opposition à un descripteur de méthode/non-donnée. Un descripteur de données a la priorité sur les dictionnaires d'instance. Désormais, une instance ne peut pas avoir un objet différent assigné au nom de la propriété et les tentatives d’attribution à la propriété déclencheront une erreur d’attribut.

2
Eryk Sun
2
Giampaolo Rodolà

Ce n'est pas vraiment une fonctionnalité cachée mais quelque chose qui pourrait être utile.

pour parcourir en boucle les éléments d'une liste

for x, y in Zip(s, s[1:]):
2
Primal Pappachan

Le module spam en Python standard

Il est utilisé à des fins de test.

Je l'ai choisi de ctypes tutoriel . Essayez vous-même:

>>> import __hello__
Hello world...
>>> type(__hello__)
<type 'module'>
>>> from __phello__ import spam
Hello world...
Hello world...
>>> type(spam)
<type 'module'>
>>> help(spam)
Help on module __phello__.spam in __phello__:

NAME
    __phello__.spam

FILE
    c:\python26\<frozen>
2
jfs

Si vous utilisez exec dans une fonction, les règles de recherche de variable changent radicalement. Les fermetures ne sont plus possibles mais Python autorise des identifiants arbitraires dans la fonction. Cela vous donne une "locale modifiable" et peut être utilisé pour importer des identifiants. En revanche, chaque recherche est plus lente, car les variables se retrouvent dans un dict plutôt que dans des fentes du cadre:

>>> def f():
...  exec "a = 42"
...  return a
... 
>>> def g():
...  a = 42
...  return a
... 
>>> import dis
>>> dis.dis(f)
  2           0 LOAD_CONST               1 ('a = 42')
              3 LOAD_CONST               0 (None)
              6 DUP_TOP             
              7 EXEC_STMT           

  3           8 LOAD_NAME                0 (a)
             11 RETURN_VALUE        
>>> dis.dis(g)
  2           0 LOAD_CONST               1 (42)
              3 STORE_FAST               0 (a)

  3           6 LOAD_FAST                0 (a)
              9 RETURN_VALUE        
2
Armin Ronacher

Gestion de la mémoire

Python alloue dynamiquement de la mémoire et utilise un garbage collection pour récupérer de l'espace inutilisé. Une fois qu'un objet est hors de portée et qu'aucune autre variable ne le référence, il sera récupéré. Je n'ai pas à m'inquiéter des dépassements de mémoire tampon et de la croissance lente des processus du serveur. La gestion de la mémoire est également une caractéristique d'autres langages dynamiques, mais Python le fait si bien.

Bien sûr, nous devons faire attention aux références circulaires et conserver les références aux objets qui ne sont plus nécessaires, mais les références faibles aident beaucoup ici.

2
Mike

Classes en tant qu'objets de première classe (illustrés par une définition de classe dynamique)

Notez également l’utilisation de la fermeture. Si cet exemple particulier ressemble à une "bonne" approche d'un problème, réexaminez-le soigneusement ... plusieurs fois :)

def makeMeANewClass(parent, value):
  class IAmAnObjectToo(parent):
    def theValue(self):
      return value
  return IAmAnObjectToo

Klass = makeMeANewClass(str, "fred")
o = Klass()
print isinstance(o, str)  # => True
print o.theValue()        # => fred
2
user166390

Jamais utilisé xrange (INT) au lieu de range (INT) .... Il utilise moins de mémoire et ne dépend pas vraiment de la taille de l'entier. Yey !! N'est-ce pas bon?

2
Mojo_Jojo

Pas du tout une particularité cachée mais quand même sympa:

import os.path as op

root_dir = op.abspath(op.join(op.dirname(__file__), ".."))

Enregistre beaucoup de caractères lors de la manipulation des chemins!

2
Luper Rouch

mapreduce en utilisant map et réduire les fonctions

créez un produit simple de cette manière:

def sumprod(x,y):
    return reduce(lambda a,b:a+b, map(lambda a, b: a*b,x,y))

exemple:

In [2]: sumprod([1,2,3],[4,5,6])
Out[2]: 32
1
locojay
>>> x=[1,1,2,'a','a',3]
>>> y = [ _x for _x in x if not _x in locals()['_[1]'] ]
>>> y
[1, 2, 'a', 3]


"locals () ['_ [1]']" est le "nom secret" de la liste en cours de création. Très utile lorsque l'état de la liste en cours de création affecte les décisions de construction ultérieures.

1
Kevin Little

Pas de fonction de programmation, mais utile en cas d'utilisation de Python avec bash ou Shell scripts.

python -c"import os; print(os.getcwd());"

Voir le documentation python ici . Des éléments supplémentaires à noter lors de l'écriture plus longue Python des scripts peuvent être vus dans cette discussion .

1
sransara

Les extensions de position et de mot-clé de Python peuvent être utilisées à la volée, et pas seulement à partir d'une liste stockée.

l=lambda x,y,z:x+y+z
a=1,2,3
print l(*a)
print l(*[a[0],2,3])

C'est généralement plus utile avec des choses comme ceci:

a=[2,3]
l(*(a+[3]))
1
Perkins

Débogage interactif de scripts (et chaînes de doctest)

Je ne pense pas que cela soit aussi connu que cela puisse être, mais ajoutez cette ligne à un script python:

import pdb; pdb.set_trace()

le débogueur de PDB apparaît avec le curseur d’exécution à cet endroit du code. Ce qui est encore moins connu, je pense, est que vous pouvez utiliser cette même ligne dans un doctest:

"""
>>> 1 in (1,2,3)   
Becomes
>>> import pdb; pdb.set_trace(); 1 in (1,2,3)
"""

Vous pouvez ensuite utiliser le débogueur pour extraire l’environnement doctest. Vous ne pouvez pas vraiment parcourir un doctest car les lignes sont exécutées de manière autonome, mais c'est un excellent outil pour déboguer les globs et l'environnement doctest.

0
shadowland

commands.getoutput

Si vous voulez obtenir le résultat d’une fonction qui renvoie directement à stdout ou stderr comme c’est le cas avec _os.system_, commands.getoutput vient à la rescousse. L'ensemble du module est juste fait de génial.

_>>> print commands.getoutput('ls')
myFile1.txt    myFile2.txt    myFile3.txt    myFile4.txt    myFile5.txt
myFile6.txt    myFile7.txt    myFile8.txt    myFile9.txt    myFile10.txt
myFile11.txt   myFile12.txt   myFile13.txt   myFile14.txt   module.py
_
0
inspectorG4dget

Dans Python 2, vous pouvez générer une représentation sous forme de chaîne d'une expression en l'enfermant avec des backticks:

 >>> `sorted`
'<built-in function sorted>'

Ceci est parti dans python 3.X.

0
Giampaolo Rodolà

Vous pouvez construire une fonction kwargs à la demande:

kwargs = {}
kwargs[str("%s__icontains" % field)] = some_value
some_function(**kwargs)

L'appel str () est en quelque sorte nécessaire, puisque python se plaint sinon qu'il ne s'agit pas d'une chaîne. Je ne sais pas pourquoi;) J'utilise ceci pour des filtres dynamiques dans le modèle d'objet Djangos:

result = model_class.objects.filter(**kwargs)
0
Martin Thurau

certaines fonctionnalités intéressantes avec réduire et opérateur.

>>> from operator import add,mul
>>> reduce(add,[1,2,3,4])
10
>>> reduce(mul,[1,2,3,4])
24
>>> reduce(add,[[1,2,3,4],[1,2,3,4]])
[1, 2, 3, 4, 1, 2, 3, 4]
>>> reduce(add,(1,2,3,4))
10
>>> reduce(mul,(1,2,3,4))
24

Voici une fonction utile que j'utilise lors du débogage des erreurs de type

def typePrint(object):
    print(str(object) + " - (" + str(type(object)) + ")")

Il imprime simplement l'entrée suivie du type, par exemple

>>> a = 101
>>> typePrint(a)
    101 - (<type 'int'>)
0
giodamelio

Multipliez une chaîne pour la faire répéter

print "SO"*5 

donne

SOSOSOSOSO
0
Rabarberski