User Tools

Site Tools


python

Python

Doc

Basics

Interactive Shell

Python est livré de base avec un shell interactif très utile. Mais il peut être utile de l'améliorer en ajoutant des petites objets custom aux petits oignons ou encore en utilisant des shells alternatifs comme ipython.

Objets custom

Il est possible d'ajouter des objets au shell via la variable d'environnement PYTHONSTARTUP=chemin_vers_le_fichier_python. Le namespace du shell contiendra alors tous les objets contenus dans le fichier indiqué.

Exemple:

def grep(pat, list, re=False):
	"""Works on list of strings.
	When 're' argument is turned on, re.search is used instead of str.find."""
	if re:
		import re
		def match(item):
			if re.search(pat, item): return True
			else: return False
	else:
		def match(item):
			if item.find(pat) >= 0: return True
			else: return False
 
	for item in list:
		if match(item):
			print item

NB: Ipython ne tient pas compte de PYTHONSTARTUP. Pour charger des trucs custom, voir ipythonrc.

Ipython

Ipython est un shell interactif amélioré (coloration syntaxique, historique inter-instances, auto-complétion et autre goodies).

Cygwin

Pour lancer ipython sur Cygwin, taper simplement ipython dans le prompt causera une erreur bash: … /usr/bin/python : Bad interpreteur : Permission Denied.

La solution la plus simple consiste à préférer ipython.bat pour lancer ipython. Un alias dans le .bashrc de cygwin permet de retrouver un jolie syntaxe.

ipythonrc

Valable pour iptyhon 0.10

Ipython possède un système de fichiers de configuration à la UNIX. Dans la version 0.10, éditer ipy_user_conf.py situé dans le répertoire .ipython dans le $HOME. Pour charger utiliser le PYTHONSTARTUP, on peut y ajouter:

def import_pystartup():
    """Import custom function in shell from PYTHONSTARTUP.
    PYTHONSTARTUP is a environnement variable shared among different python shells."""
    import os
    filename = os.environ.get('PYTHONSTARTUP')
    if filename and os.path.isfile(filename):
        # execfile(filename) # Can't use builtin execfile function in ipython...
		execf(filename)

sans oublier d'appeler cette fonction dans le main.

Unicode

RegExp

PyGTK

Tkinter

WxWidget

Threading

Advanced Python

Best practices

Programmation événementielle

Profilage, optimisation et performances

Recipes

  • Convert a youtube transcript in srt subtitle
    #!/usr/bin/python
    # -*- encoding:utf-8 -*-
     
    """Translate Google's Transcript into srt file.
     
    Takes google's transcript filename as argument (xml extension required).
     
    NB: to get google's transcript, use tihs URL:
    http://video.google.com/timedtext?lang=en&v=VIDEO_ID
    """
     
    # srt example
    """1
    00:00:20,672 --> 00:00:24,972
    Entre l’Australia et la South America,
    dans l’Océan South Pacific…"""
     
    # Google's transcript example (first tags)
    """<?xml version="1.0" encoding="utf-8" ?>
    <transcript>
    <text start="11.927" dur="2.483">
    This is a matter of National Security.</text>"""
     
    import re, sys
     
    # Pattern to identify a subtitle and grab start, duration and text.
    pat = re.compile(r'<?text start="(\d+\.\d+)" dur="(\d+\.\d+)">(.*)</text>?')
     
    def parseLine(text):
    	"""Parse a subtitle."""
    	m = re.match(pat, text)
    	if m:
    		return (m.group(1), m.group(2), m.group(3))
    	else:
    		return None
     
    def formatSrtTime(secTime):
    	"""Convert a time in seconds (google's transcript) to srt time format."""
    	sec, micro = str(secTime).split('.')
    	m, s = divmod(int(sec), 60)
    	h, m = divmod(m, 60)
    	return "{:02}:{:02}:{:02},{}".format(h,m,s,micro)
     
    def convertHtml(text):
    	"""A few HTML encodings replacements.
    	&amp;#39; to '
    	&amp;quot; to "
    	"""
    	return text.replace('&amp;#39;', "'").replace('&amp;quot;', '"')
     
    def printSrtLine(i, elms):
    	"""Print a subtitle in srt format."""
    	return "{}\n{} --> {}\n{}\n\n".format(i, formatSrtTime(elms[0]), formatSrtTime(float(elms[0])+float(elms[1])), convertHtml(elms[2]))
     
    fileName = sys.argv[1]
     
    def main(fileName):
    	"""Parse google's transcript and write the converted data in srt format."""
    	with open(sys.argv[1], 'r') as infile:
    		buf = []
    		for line in infile:
    			buf.append(line.rstrip('\n'))
    	# Split the buffer to get one string per tag.
    	buf = "".join(buf).split('><')
    	i = 0
    	srtfileName = fileName.replace('.xml', '.srt')
    	with open(srtfileName, 'w') as outfile:
    		for text in buf:
    			parsed = parseLine(text)
    			if parsed:
    				i += 1
    				outfile.write(printSrtLine(i, parsed))
    	print('DONE ({})'.format(srtfileName))
     
    if __name__ == "__main__":
    	main(fileName)

Advocacy

ErrorMsg

  • re:
    • sre_constants.error: invalid group reference Soultion (group substitution: \g<1>)

Common Bad Programming Pattern

Référence à un objet

Lorsque l'on fait un assignement sur un objet, Python réalise une copie par référence (sorte de pointeur, hard link). Tout assignement sur le nouveau nom affecte naturellement le premier nom puisqu'ils référencent le même objet.

class A():
    c = 1
a = A()
b = a
b.c = 2
# a.c returns 2
d = A.c
e = d
e = 2
# d.c returns 1

Cependant, lorsque l'on fait un assignement sur un attribut d'un object, le nom vient référencer la valeur retournée par l'attribut. L'assignement d'une nouvelle valeur ne modifira pas la valeur de l'attribut de l'objet. Cela se comprend facilement:

a = A()
>>> a # returns <class __main__.A at 0x02433150> (la référence)
b = a.c
>>> b # returns 1 (la valeur)

Pour référencer l'attribut d'un objet, utiliser getattr (super puissant!)

f = getattr(a, "c")

Cool Stuff

python.txt · Last modified: 2014/09/13 14:03 by ginko