Py: Divers
Py: Divers

Directory

Liens

Programmation asynchrone

Livres


Color trackBack

try:
    import IPython.core.ultratb
except ImportError:
    # No IPython. Use default exception printing.
    pass
else:
    import sys
    sys.excepthook = IPython.core.ultratb.ColorTB()

ou

import sys, IPython.core.ultratb
sys.excepthook = IPython.core.ultratb.ColorTB(color_scheme='LightBG')
sudo pip3 install colored-traceback

Classe de base: Object

En python 3 il n’est plus nécéssaire d’explicitement dire à Python qu’une classe hérite de la classe de base object.

class Parent():
    def __init__(self):
        pass

Cette classe hérite implicitement de la classe object

Poids (bytes) d’une structure de données

>>> a = [1,2,3,4]
>>> print(sys.getsizeof(a))
96

np.array vs lists

NumPy’s arrays are more compact than Python lists – a list of lists as you describe, in Python, would take at least 20 MB or so, while a NumPy 3D array with single-precision floats in the cells would fit in 4 MB. Access in reading and writing items is also faster with NumPy.

Maybe you don’t care that much for just a million cells, but you definitely would for a billion cells – neither approach would fit in a 32-bit architecture, but with 64-bit builds NumPy would get away with 4 GB or so, Python alone would need at least about 12 GB (lots of pointers which double in size) – a much costlier piece of hardware!

The difference is mostly due to “indirectness” – a Python list is an array of pointers to Python objects, at least 4 bytes per pointer plus 16 bytes for even the smallest Python object (4 for type pointer, 4 for reference count, 4 for value – and the memory allocators rounds up to 16). A NumPy array is an array of uniform values – single-precision numbers takes 4 bytes each, double-precision ones, 8 bytes. Less flexible, but you pay substantially for the flexibility of standard Python lists!

Shallow and deep copy

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other. This module provides generic shallow and deep copy operations.

import copy

Return a shallow copy of x:

copy.copy(x)

Return a deep copy of x:

copy.deepcopy(x)
  • A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

  • A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

In order for a class to define its own copy implementation, it can define special methods __copy__() and __deepcopy__(). The former is called to implement the shallow copy operation; no additional arguments are passed. The latter is called to implement the deep copy operation; it is passed one argument, the memo dictionary. If the __deepcopy__() implementation needs to make a deep copy of a component, it should call the deepcopy() function with the component as first argument and the memo dictionary as second argument.

if __name__ == ‘__main__’

C’est une expression idiomatique qu’on utilise en Python pour éviter de lancer une partie de code si on importe ce script dans un autre.

# fichier poule.py

def poule():
    print("cotCot")

poule()

Suite à:

  • ./poule.py dans un terminal la fonction poule() sera lancée
  • import poule **dans un autre script** la fonction poule()` sera lancée aussi

Ce n’est pas forcément ce qu’on veut et le code suivant permet d’éviter ça.

# fichier poule.py

def poule():
    print("cotCot")

if __name__ == '__main__':
    poule()

De cette façon si on fait ./poule.py va lancer poule() mais pas import poule dans un autre scripte.

Explication

La variable __name__ est une variable automatiquement créée par Python, toujours disponible, dans tous les scripts. Elle contient le nom du script courant si on importe le script.

Si le script est le script principal, alors __name__ ne content pas le nom du script mais une string qui contient __main__.

# fichier fichier_poule.py

print(__name__)

output:

__main__
# fichier fichier_cochon.py

import poule

output:

fichier_poule

Sources

samEtMax

API

A étoffer!
En bref, c’est une interface.

Tricks

Enumerate

Bad way:

ferme = ["vache", "poule", "cochon", "mouton"]

c = 0
for i in ferme:
    print(c, i)
    i += 1

enumerate’s way:

ferme = ["vache", "poule", "cochon", "mouton"]

for c, i in enumerate(ferme):
    print(c, i)

Inline if-else statement (Operateur ternaire)

<expression> if <condition> else <expression2>

result = x if a > b else y

x = 2
print("yep") if (x == 2) else print("nop")

Lettre de l’alphabet dans une liste

letters = [chr(i) for i in range(ord('a'), ord('j')+1)]

Being pythonic

Regular way (C like):

>>> alph = []
>>> for i in range(ord('A'), ord('Z')+1):
...     alph.append(chr(i))
... 
>>> print(alph)
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
>>>
>>>
>>> l = []
>>> for i in range(10):
...     for j in alph[:10]:
...         l.append(j+str(i))
...
>>>
>>>
>>>for i, j in enumerate(l):
...     if (i % 10 == 0) and (i > 0):
...         print()
...     print(j, end=' ')
...
A0 B0 C0 D0 E0 F0 G0 H0 I0 J0
A1 B1 C1 D1 E1 F1 G1 H1 I1 J1
A2 B2 C2 D2 E2 F2 G2 H2 I2 J2
A3 B3 C3 D3 E3 F3 G3 H3 I3 J3
A4 B4 C4 D4 E4 F4 G4 H4 I4 J4
A5 B5 C5 D5 E5 F5 G5 H5 I5 J5
A6 B6 C6 D6 E6 F6 G6 H6 I6 J6
A7 B7 C7 D7 E7 F7 G7 H7 I7 J7
A8 B8 C8 D8 E8 F8 G8 H8 I8 J8
A9 B9 C9 D9 E9 F9 G9 H9 I9 J9

Pythonic way:

a = [chr(i) for i in range(ord('A'), ord('J') + 1)]

b = [i + str(j) for j in range(10) for i in a]

print(''.join('\n'+b[i]+' ' if i%10==0 and i>0 else b[i]+' ' 
                for i in range(len(b))))

A0 B0 C0 D0 E0 F0 G0 H0 I0 J0
A1 B1 C1 D1 E1 F1 G1 H1 I1 J1
A2 B2 C2 D2 E2 F2 G2 H2 I2 J2
A3 B3 C3 D3 E3 F3 G3 H3 I3 J3
A4 B4 C4 D4 E4 F4 G4 H4 I4 J4
A5 B5 C5 D5 E5 F5 G5 H5 I5 J5
A6 B6 C6 D6 E6 F6 G6 H6 I6 J6
A7 B7 C7 D7 E7 F7 G7 H7 I7 J7
A8 B8 C8 D8 E8 F8 G8 H8 I8 J8
A9 B9 C9 D9 E9 F9 G9 H9 I9 J9

Read char from the input

class _Getch:
    ''' Gets a single char grom stdin. 
    Does not echo to the screen '''
    
    def __init__(self):
        try:
            self.impl = _GetchWindows()
        except ImportError:
            self.impl = _GetchUnix()
        
    def __call__(self): return self.impl()


class _GetchUnix:
    def __init__(self):
        import tty, sys
    
    def __call__(self):
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)

        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

        return ch


class _GetchWindows:
    def __init__(self):
        import msvcrt
    
    def __call__(self):
        import msvcrt
        return msvcrt.getch()

# getch = _Getch()
# key   = getch.__call__()

# print("Pressed key is: ", key)