Python 2

De Banane Atomic
Aller à la navigationAller à la recherche

Console I/O

Python.svg
# Affiche le texte et attend une saisie
nombre = raw_input('Entrez un nombre > ')
print(nombre)

# Afficher du texte dans la console. %r est remplacé par la variable correspondante.
print "Texte %r %r." % (variable1, variable2)

# Afficher du texte sans retour à la ligne mais avec un espace à la fin
print "Texte",
print("Texte"),

Manipulation de string

Python.svg
# concaténation
chaine2 = chaine1 + "chaine"
# ici avec %s, chaine1 est converti en string via la méthode str()
chaine2 = "%schaine" % (chaine1)
# l'opérateur += est déjà optimisé, un StringBuilder est inutile
chaine1 += ";"

# rechercher un sous-élément, retourne l'index du sous-élément sinon -1
chaine1.find('element2')

# remplacer les . par des !
chaine2 = chaine1.replace(".", "!")

# accès par indice
chaine = "chaine"
chaine[0] # c
chaine[0:2] # ch
chaine[:2]  # ch
chaine[2:4] # ai
chaine[2:]  # aine
chaine[-1]  # e
chaine[-2]  # n
chaine[-2:] # ne
chaine[:-2] # chai

# longueur de la chaîne
longueur = len(chaine) # 6

# test si une chaîne est vide: empty strings are "falsy"
if not chaine1:
    # chaine1 est vide

%s vs %r

%s réalise une convertion avec str(), alors que %r utilise repr().
repr() retourne une syntaxe python valide et qui permet de manière non ambigu de reconstruire l'objet de base.

Python.svg
d = datetime.date.today()
str(d) # '2011-05-14'
repr(d) # 'datetime.date(2011, 5, 14)'

Encodage

Python.svg
# Encodage par défaut
import sys
print(sys.getdefaultencoding())
# ascii

# Jeu de caractères par défaut de l'utilisateur
import locale
print(locale.getdefaultlocale())
# ('fr_FR', 'cp1252')

# Jeu de caractères de la console
import sys
print(sys.stdout.encoding)
# cp580
Python.svg
# Par défaut une chaîne de caractère est un string de 8 bits (cp1252)
"é"
# '\x82' dans le jeu de caractères de la console : cp850

# mais on peut forcer l'utilisation d'un objet unicode (utf-8)
u"é"
# u'\xe9' dans le jeu de caractères de l'utilisateur : cp1252
Python.svg
# Spécifier l'encodage du script. Ce commentaire doit se trouver dans les 2 premières lignes du script.
# coding: utf-8

Une autre solution pour spécifier l'encodage du script est de convertir le fichier en UTF-8 avec BOM. Ce qui équivaut à la ligne # coding: utf-8

Exemple

Fichier encodé en ANSI

Python.svg
#!/usr/bin/env python
# coding: cp1252

print unicode("é褀", 'cp1252').encode('cp850', 'replace')
# éè¤?

Fichier encodé en UTF-8 sans BOM

Python.svg
#!/usr/bin/env python
# coding: utf-8

print "é"
# ├®

print u"é"
# é

Convertion UTF-8 → cp580

Python.svg
# Lecture d'un fichier encodé en UTF-8 et affichage dans la console
file = open('monfichier.txt', 'r')
print file.read().decode('utf-8').encode(sys.stdout.encoding, 'replace')
UTF-8 Unicode cp850
.decode('utf-8') .encode('cp850')
Le fichier en entrée Chaîne Python La console en sortie

OpenPyXL

Openpyxl is a Python library for reading and writing Excel 2010 xlsx/xlsm/xltx/xltm files.

Python.svg
#!/usr/bin/env python

import sys
import os, os.path
import openpyxl
import csv

if len(sys.argv) != 2:
    exit('Utilisation: {} /path/to/file.xlsx'.format(os.path.basename(sys.argv[0])))

wb = openpyxl.load_workbook(sys.argv[1])
sh = wb.get_active_sheet()
with open('Data.csv', 'w') as f:
    csv_writer = csv.writer(f)
    for row in sh.rows:
        csv_writer.writerow([cell.value for cell in row])

ftplib

Python.svg
from ftplib import FTP

ftp = FTP('adresse ftp', 'identifiant', 'mot de passe')
ftp.cwd("dossier") # se rendre dans le répertoire dossier
ftp.mkd("dossier") # erreur si le dossier existe déjà rendre dans le répertoire dossier
# Ouvrir le fichier en lecture binaire
fichier = open('chemin vers un fichier','rb')
# Envoyer en mode bianire le fichier vers le serveur ftp
ftp.storbinary('STOR xxx.pdf', fichier)
fichier.close()
ftp.quit()
Python.svg
# Afficher la progression d'envoie du fichier
progress = FtpProgess('chemin vers un fichier')
ftp.storbinary('STOR xxx.pdf', fichier, callback=progress.FtpCallback)

class FtpProgess:
	def __init__(self, filePath):
		# Stockage de la taille du fichier
		self.FileSize = os.path.getsize(filePath)
		self.DataSentSum = 0
		self.PreviousPercentage = 0
		
	def FtpCallback(self, buffer):
		# Par défaut les blocks envoyés ont une taille de 8192 octets
		# traiter le cas ou la taille du fichier est inférieure à 8192 octets
		self.DataSentSum += 8192
		
		if not self.PreviousPercentage == self.DataSentSum * 100 / self.FileSize:
			self.PreviousPercentage = self.DataSentSum * 100 / self.FileSize
			print "%s%%" % self.PreviousPercentage

# Callback plus basic
def FtpCallback(buffer):
	print "."

Envoyer un email

smtplib

Python.svg
sender = 'Nom <sender@domaine.fr>'
receiver = 'receiver@domaine.fr'

message = """From: sender@domaine.fr
To: receiver@domaine.fr
MIME-Version: 1.0
Content-type: text/html
Subject: Mon sujet

<h1>Titre</h1>
%s
""" % texte

try:
   smtpObj = smtplib.SMTP('localhost')
   smtpObj.sendmail(sender, receiver, message)         
   print ("Successfully sent email")
except Exception as e:
   print ("Error: unable to send email\n%s" % e)

IMAPClient

Bash.svg
# installation
sudo pip2 install imapclient
Python.svg
from imapclient import IMAPClient
import email

HOST = 'imap.gmail.com'
USERNAME = 'compte@gmail.com'
PASSWORD = 'pass'
ssl = True

server = IMAPClient(HOST, use_uid=True, ssl=ssl)
try:
    server.login(USERNAME, PASSWORD)
except IMAPClient.Error as e:
    exit(e)

select_info = server.select_folder('INBOX')
messages = server.search(['UNSEEN'])
print "%d messages non-lus" % len(messages)

print
print "Messages:"
response = server.fetch(messages, ['RFC822'])
for msgid, data in response.iteritems():
    msg = email.message_from_string(data['RFC822'])
    print msg['subject']
    print msg['from']
    print msg.get_payload(0) # texte du message

server.logout()

Tkinter

Bibliothèque permettant de faire des interfaces graphiques en Python.

Python.svg
from Tkinter import *

root = Tk()
root.title('Message')
Message(root, text="Text", bg='royalblue', fg='ivory', relief=GROOVE)
    .pack(padx=10, pady=10)
root.mainloop()

API Windows

Python Win32 Extensions

Gnome Keyring

Bash.svg
# Installez les bindings pour libgnome-keyring
sudo pacman -S python2-gnomekeyring
Python.svg
#!/usr/bin/env python

import gnomekeyring as GnomeKeyring

# parcourt de toutes les entrées de tous les trousseaux
for keyring in GnomeKeyring.list_keyring_names_sync():
    for id in GnomeKeyring.list_item_ids_sync(keyring):
        item = GnomeKeyring.item_get_info_sync(keyring, id)
        print("[trousseau: %s] description: %s = mot de passe: %s" % 
            (keyring, item.get_display_name(), item.get_secret())
    else:
        if len(GnomeKeyring.list_item_ids_sync(keyring)) == 0:
            print '[trousseau: %s] --empty--' % keyring


# trousseau par défaut : login
keyring = GnomeKeyring.get_default_keyring_sync() 

# création d'une nouvelle entrée dans le trousseau par défaut
GnomeKeyring.item_create_sync(
    keyring, GnomeKeyring.ITEM_GENERIC_SECRET, "description de l'entrée", 
   { "attribut1" : "valeur", "attribut2" : "valeur" }, "mot de passe", True)

# recherche à partir de la description de l'entrée dans le trousseau par défaut
for id in GnomeKeyring.list_item_ids_sync(keyring):
    item = GnomeKeyring.item_get_info_sync(keyring, id)
    if item.get_display_name() == "GMail Checker":
        print("pass: %s" % item.get_secret())
        break
else:
    print("Entry not found in Gnome Keyring")

# recherche à partir des attributs
try:
    # recherche une entrée qui possède au moins l'attribut spécifié à la bonne valeur
    matches = GnomeKeyring.find_items_sync(
        GnomeKeyring.ITEM_GENERIC_SECRET, {"attribut1" : "valeur"});
    for match in matches:
        info = GnomeKeyring.item_get_info_sync(keyring, match.item_id)
        print("name: %s ; id: %s ; pass: %s; attributs: %s" % 
            (info.get_display_name(), match.item_id, match.secret, match.attributes))
except GnomeKeyring.NoMatchError:
    print "Attribut not found in Gnome Keyring"

Script Nautilus

Python.svg
#!/usr/bin/env python

import os

# Pour chaque fichier séléctionné
for f in os.environ['NAUTILUS_SCRIPT_SELECTED_FILE_PATHS'].splitlines():

Script Python PyUNO

DocumentConverter (Windows)

Sous Windows, il est conseillé d'utiliser l'exécutable Python d'OpenOffice car il est déjà configurer pour utiliser UNO. Le script Python DocumentConverter est disponible ici. Il semble pouvoir fonctionner sur Linux aussi, même si UnoConv semble plus pratique.

Dos.svg
REM lancement d'OpenOffice en mode serveur
"C:\Program Files\OpenOffice.org 3\program\soffice.exe" -headless -nofirststartwizard -accept=socket,host=localhost,port=2002;urp;"

REM utilisation du script DocumentConverter.py
"C:\Program Files\OpenOffice.org 3\program\python.exe" DocumentConvert.py document.odt sortie.pdf

UnoConv (Linux)

Script python, fonctionnant sous Linux et installable via Synaptic

Bash.svg
# Convertion d'un document odt en pdf
unoconv -f pdf Document.odt

Scripts réutilisables

CopyFiles

Équivalent de shutil.copytree, sauf que destination peut déjà exister. L'exclusion des fichiers se fait ici à l'aide d'une expression rationnelle.

Python.svg
def CopyFiles(source, destination):
    print "CopyFiles " + source + " -> " + destination
    if not os.path.exists(destination):
        os.mkdir(destination)
    for filename in os.listdir(source):
        if not re.match(exclusion, filename):
            #print os.path.join(source, filename) + " -> " + destination
            if os.path.isfile(os.path.join(source, filename)):
                shutil.copy(os.path.join(source, filename), destination)
            else:
                # pour les répertoires
                CopyFiles(os.path.join(source, filename), os.path.join(destination, filename))

Erreurs

TypeError: not all arguments converted during string formatting

Mauvaise utilisation du formatage d'un string.

Python.svg
# erreur: 2 variables pour un remplacement
'texte %r." % (variable1 ,variable2)

SyntaxError: Non-ASCII character

Depuis Python 2.3 il faut préciser l'encodage au début du script pour disposer de l'ASCII étendu, ISO ou UTF.

Python.svg
#!/usr/bin/env python
# *-* coding: iso-8859-1 *-*

invalid syntax with print

print "Hello" SyntaxError: invalid syntax
En python 3.*, la fonction print doit être utilisée avec de parenthèses.

unicodeescape

SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-4: truncated \UXXXXXXXX escape
Une chaîne de caractères contient \U qui est compris comme un Unicode escape de 8 caractères. Pour éviter cela, il suffit de doubler les \ ou bien de préfixer la chaîne avec r : r'ma chaine'.

Exemples

ConverToANSI

Script utilisé par Nautilus pour encoder les fichiers UTF-8 en ASCII.

Python.svg
#!/usr/bin/env python
# *-* coding: iso-8859-1 *-*

# installer python-tk pour pouvoir utiliser Tkinter pour l'affichage de la message box.

import sys
import os
from Tkinter import *
import codecs

global filesConverted
filesConverted = []

def Convert(filePath):
	fichier = open(filePath, "rb")
	contenuDuFichier = fichier.read()
	contenuDuFichier = contenuDuFichier.decode("utf-8")
	fichier.close()

	contenuDuFichier = contenuDuFichier.encode("ASCII", 'replace')

	fichierTemp = open("tempASCII", "w")
	fichierTemp.write(contenuDuFichier)
	fichierTemp.close()

	os.remove(filePath)
	os.rename("tempASCII", filePath)
	filesConverted.append(filePath + "\n")


for path in os.environ['NAUTILUS_SCRIPT_SELECTED_FILE_PATHS'].splitlines():
	if os.path.isfile(path):
		Convert(path)
	else:
		for root, dirs, files in os.walk(path):
			for fileName in files:
				Convert(os.path.join(root, fileName))

root = Tk()
root.title('Résultat de la conversion')
Label(root, text="".join(filesConverted)).pack(padx=10, pady=10)
root.mainloop()

SendToFTP

Script utilisé par Nautilus pour uploader un fichier vers un serveur FTP.

Python.svg
#!/usr/bin/env python

# installer python-tk pour pouvoir utiliser Tkinter pour l'affichage de la message box.

import sys
import os
from ftplib import FTP
from Tkinter import *

global ftp

def SendFile(filePath):
	fileNameForFtp = filePath.rsplit('/', 1)[1].
                                replace(" - ", "_").
                                replace(" ", "_").replace("#", "Sharp")
	fichier = open(filePath, "rb")
	ftp.storbinary("STOR " + fileNameForFtp, fichier)
	fichier.close()


ftp = FTP("bananeatomic.free.fr", "bananeatomic", "gt27h!i1")
ftp.cwd("files")

for selectedPath in os.environ['NAUTILUS_SCRIPT_SELECTED_FILE_PATHS'].splitlines():
	if os.path.isdir(selectedPath): # si c'est un dossier
		for filePath in os.listdir(selectedPath):
			if os.path.splitext(filePath)[1] == ".pdf":
				SendFile(os.path.join(selectedPath, filePath))
	else: # si c'est un fichier
		SendFile(selectedPath)
ftp.quit()

messageBox = Tk()
messageBox.title("Message")
Label(messageBox, text=os.environ['NAUTILUS_SCRIPT_SELECTED_FILE_PATHS']).
     pack(padx=10, pady=10)
messageBox.mainloop()

ConvToPdfSendToFTP

Script utilisé par Nautilus pour convertir un fichier odt en pdf et ensuite l'uploader vers un serveur FTP.

Python.svg
#!/usr/bin/env python
# *-* coding: iso-8859-1 *-*

# installer python-tk pour pouvoir utiliser Tkinter pour l'affichage de la message box.

import sys
import os, os.path
import time
from ftplib import FTP
from Tkinter import *

global ftp


def CreatePDF(odtFilePath):
	os.system("unoconv -f pdf \"%s\"" % (odtFilePath))
# CreatePDF


def SendPDF(odtFilePath):
	pathToFile = os.path.dirname(odtFilePath)
	fileName = os.path.basename(odtFilePath)
	
	# on remplace les caractères " - ", " ", et "#"
	fileNameForFtp = fileName.replace(" - ", "_").
                                replace(" ", "_").replace("#", "Sharp")
	# comme c'est le fichier odt qui a été sélectionné, 
	# on modifie l'extension en pdf
	fileNameForFtp = os.path.splitext(fileNameForFtp)[0] + ".pdf"
	pdfFilePath = os.path.splitext(odtFilePath)[0] + ".pdf"

	fichier = open(pdfFilePath, "rb")
	ftp.storbinary("STOR " + fileNameForFtp, fichier)
	fichier.close()
# SendPDF

ftp = FTP("bananeatomic.free.fr", "bananeatomic", "gt27h!i1")
ftp.cwd("files")

for selectedPath in os.environ['NAUTILUS_SCRIPT_SELECTED_FILE_PATHS'].splitlines():
#for selectedPath in sys.argv:
	if os.path.isdir(selectedPath): # si c'est un dossier
		for filePath in os.listdir(selectedPath):
			if os.path.splitext(filePath)[1] == ".odt":
				CreatePDF(os.path.join(selectedPath, filePath))
				SendPDF(os.path.join(selectedPath, filePath))
	else: # si c'est un fichier
		CreatePDF(selectedPath)
		SendPDF(selectedPath)
ftp.quit()

messageBox = Tk()
messageBox.title("Message")
Label(messageBox, text=os.environ['NAUTILUS_SCRIPT_SELECTED_FILE_PATHS']).
    pack(padx=10, pady=10)
messageBox.mainloop()