Upload
pierre-alban-dewitte
View
93
Download
1
Embed Size (px)
Citation preview
BreizhCamp 2015
#BzhCmp
#python #bzhcmp
BreizhCamp 2015
#BzhCmp
Python après 15 ans de JAVA
Pierre-Alban DEWITTE - @__pad__
dev.myscript.com
PYTHON
● Langage généraliste● Dynamiquement typé● Orienté objet● Fonctionnel● Gestion de la mémoire par un garbage
collector
PYTHON
● Créé par Guido van Rossum
● Version 0.9 datant de 1991● Version 1.0 datant de 1994
● Développé par la communauté● Code détenu par la Python Software
Fundation● Evolution à travers des PEP (≈JSR)
PYTHON
Python 2 ou Python 3
● Quelques changement de syntaxe● Portée des variables limitées
● Fusion de librairies● Utilisation de l’UTF-8 par défaut● Exceptions
Python 2 ou Python 3
for ind in [1, 2, 3]: squared = [ind**2 for ind in (20, 30, 40, 50)] print(ind)
● Contraint par l’environnement● Contraint par des librairies
http://python3wos.appspot.com/ et notamment Spark
● Vous voulez utiliser Jython
Pourquoi choisir Python 2
Le langage
● Bye bye les accolades !● Ne pas mélanger espaces et
tabulations
Identation
• En python3 toute les chaines sont unicodes (comme java)
• Le préfixe r indique de ne pas échapper la chaine
• Nombreuses fonctions disponibles nativement
System.out.println()
c: emp\dirc:\temp\dirc:\\temp\dir
print('c:\temp\dir')print('c:\\temp\dir')print(r'c:\temp\dir')
● List est un type natif● Les tuples sont des listes immutables● Les fonctions de manipulation sont
intégrées au langage● Comme si Guava était inclus
nativement
ArrayList
ArrayList
uneListe = ['Morbihan', 'Finistère', 'Côtes-d''Armor', 'Ile et Vilaine']uneListe.append('Loire-Atlantique')uneListe.append(50)print(uneListe)uneListe.pop()print(uneListe)unTuple = (22, 29, 56, 35)print(unTuple)
['Morbihan', 'Finistère', 'Côtes-dArmor', 'Ile et Vilaine', 'Loire-Atlantique', 50]
['Morbihan', 'Finistère', 'Côtes-dArmor', 'Ile et Vilaine', 'Loire-Atlantique']
(22, 29, 56, 35)
ArrayList
print(unTuple)# Dernier élémentprint(unTuple[-1])# Entre le second et l'avant dernier élémentprint(unTuple[1:-1])# Un élément sur deux de la listeprint(unTuple[::2])# En inversant l'ordreprint(unTuple[::-1])
(22, 29, 56, 35)35
(29, 56)(22, 56)
(35, 56, 29, 22)
ArrayList
# Equivalent du .equals() en Javaprint(copie == uneListe)# Equivalent du == en Javaprint(copie is uneListe)# Equivalent du hashCode() en javaprint(id(copie), id(uneListe))
TrueFalse
51316416 51315096
ArrayList
print("for ... in ...")for dpt in uneListe: print(dpt)print("for ... in enumerate(...)")for idx, dpt in enumerate(uneListe): print(idx, " -> ", dpt)
for ... in ...Morbihan
...Loire-Atlantique
for ... in enumerate(...)0 -> Morbihan
...4 -> Loire-Atlantique
ArrayList
if 'Morbihan' in uneListe : print("A moitié bretons")uneListe.remove('Morbihan')print(uneListe)uneListe.sort()print(uneListe)
A moitié bretons
['Finistère', 'Côtes-dArmor', 'Ile et Vilaine', 'Loire-Atlantique']
['Côtes-dArmor', 'Finistère', 'Ile et Vilaine', 'Loire-Atlantique']
Set
# Création de la patte à galettemyset = {'farine', 'eau', 'sel', 'oeufs'}print(myset)# Finalement double dose de farinemyset.add('farine')print(myset)# Jamais de la vie avec des oeufsmyset.remove('oeufs')print(myset)
{'eau', 'sel', 'farine', 'oeufs'}{'eau', 'sel', 'farine', 'oeufs'}
{'eau', 'sel', 'farine'}
Map
mydict = { # Tableau comme valeur 'ingredients': ['farine', 'eau'], # Set comme valeur 'ustensiles': {'spatule', 'poele'}, # Tout type 'duree': 10, # Imbrication des dictionaires entre eux 'difficulte': { 'debutants': 'facile', 'experimente': 'super facile'}}print(mydict)mydict.pop('ustensiles')print(json.dumps(mydict, indent=2, separators=(',', ': ')))
Map
{'ustensiles': {'poele', 'spatule'}, 'duree': 10, 'difficulte': {'debutants': 'facile', 'experimente': 'super facile'}, 'ingredients': ['farine', 'eau']}
{ "duree": 10, "difficulte": { "debutants": "facile", "experimente": "super facile" }, "ingredients": [ "farine", "eau" ]}
Fonctions
def ma_fonction(arg1, arg2="default", *args, **kwargs): # arg1 est obligatoire print("arg1:", arg1) # arg2 optionel avec une valeur par défaut print("arg2:", arg2) # args est un tableau print("args:", args) # kwargs est un dictionnaire print("kwargs:", kwargs)
if __name__ == '__main__': print('########### appel 1 ###########') ma_fonction('1') print('########### appel 2 ###########') ma_fonction('2', 'la','decl.', 'est', 'flexible',vous_en='pensez quoi ?')
Fonctions
########### appel 1 ###########arg1: 1arg2: defaultargs: ()kwargs: {}
########### appel 2 ###########arg1: 2arg2: laargs: ('declaration', 'est', 'tres', 'flexible')kwargs: {'pensez': 'quoi ?', 'vous': 'en'}
Classes
class MaClasse(object): def __init__(self, transform):
self.attribut = 'un attribut' self.transform = transform def affiche(self): print(self.transform(self.attribut))
if __name__ == '__main__': uneIntance = MaClasse(lambda x:x.upper()) uneIntance.affiche()
UN ATTRIBUT
● Favoriser autant que possible l’utilisation de fonctions
● Toujours préférer une fonction à l’utilisation de l’héritage
Classes et fonctions
● Notion de package comme en java● Un répertoire doit contenir un fichier
__init__.py● Possibilité d’importer un package dans
son intégralité ou bien seulement un module
● Le mot clé as permet de gérer les éventuels conflits de nommage
● Recherche relativement à la variable PYTHON_PATH
Import
Et vraiment beaucoup de choses
Eco-système
● De nombreuses librairies sont disponibles dans le runtime Python
● Eco-système très riche et très communautaire
Librairies
Librairies natives
Jetty <> http.server
python –m http.server 8080
● Utile créer un serveur HTTP minimaliste
Documentationdef max(*args, key=None):
"""max(iterable, *[, default=obj, key=func]) -> valuemax(arg1, arg2, *args, *[, key=func]) -> value With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument."""
pydoc permet de générer la doc
JUNIT, TestNG <> unittest
import unittest
def fun(x,y): return x + y
class MyTest(unittest.TestCase): def setUp(self): self.inc = 1
def test_premier(self): self.assertEqual(fun(3,self.inc), 4)
def test_second(self): self.assertEqual(fun(3,self.inc), 'wrong')
Mockito <> unittest.mock
from unittest.mock import MagicMock
class ProductionClass(object): def method(self): self.something(1, 2, 3)
def something(self, a, b, c): pass
real = ProductionClass()real.something = MagicMock()real.method()real.something.assert_called_once_with(1, 2, 3)
Dans la librairie standard depuis Python 3.3
● Extrêmement complet● Attention à ne bien initialiser qu’une
fois● Pas tout le temps compatible avec
d’autre modules (multithread windows par exemple)
xxx4J, LogPack <>Logging
import logginglogging.basicConfig(filename='example.log',level=logging.DEBUG)logging.debug('This message should go to the log file')logging.info('So should this')logging.warning('And this, too')
Jackson <> json
json_string = '{"first_name": "Guido", "last_name":"Rossum"}'parsed_json = json.loads(json_string)print(parsed_json['first_name'])d = { 'first_name': 'Guido', 'titles': ['BDFL', 'Developer'],}print(json.dumps(d, sort_keys=True, indent=4))
Guido{ "first_name": "Guido", "titles": [ "BDFL", "Developer" ]}
Autres équivalences
JAVA PYTHONCommons IO os, shutil,
subprocess et sysCommons Collections
collections
Commons Codec codecsGuava Ba y’en a pas
besoin
Gestion des dépendances
● Pip est le gestionnaire de dépendance couramment utilisé
● Par convention la liste des dépendance est contenue dans le fichier requirements.txt
● Pour installer / upgrader
Gestion des dépendances
pymongo==2.8.0pymssql==2.1.1
pip install requirements.txt
Virtualenv
● VENV permet d’isoler un environnement d’éxécution
● Permet de figer une version de Python et les dépendances
● Absolument nécessaire en toute occasion
python -m venv myenv
myenv/Scripts/activate.bat
Librairies disponibles dans PyPi
Jodatime <> dateutil
from dateutil.relativedelta import *from dateutil.easter import *from dateutil.rrule import *from dateutil.parser import *now = parse("Sat May 30 15:20:08 GMT 2015")today = now.date()year = rrule(YEARLY,bymonth=8,bymonthday=13,byweekday=FR)[0].yearrdelta = relativedelta(easter(year), today)print(…)
Today is: 2015-05-30Year with next Aug 13th on a Friday is: 2021
How far is the Easter of that year: relativedelta(years=+5, months=+10, days=+5)And the Easter of that year is: 2021-04-04
HTTPClient <> Requests
r = requests.get('https://…/json', auth=('u','p'))print(r.status_code)print(r.headers['content-type'])os.system("pause")print(r.text)os.system("pause")print(r.json()['releases']['1.0.4 '])
● Mises à jour de sécurité fréquentes
● Pool de connections● Gestion multi-part● Persistance de cookies● …
Bootle <> Spring MVC
from bottle import get, post, request # or route@get('/login') # or @route('/login')def login(): return '''<form action="/login … '''@post('/login') # or @route('/login', method='POST')def do_login(): username = request.forms.get('username') if check_login(username, password): return "<p>Your login was correct.</p>" else: return "<p>Login failed.</p>"
● Template, routing, serialization …
● SQLAlchemy est Spring JDBC et Hibernate réunis
● DJANGO est à Python de que Grails est à Groovy
● Des librairies scientifique pour grapher des résultats
● Spark et son API PYTHON● Des drivers pour toutes les bases de
données No-SQL● …
Et aussi
PEP8
● classes : CorrectClassName● exceptions : IncorrectClassNameError
(suffixe "Error" !)● fonctions : get_correct_number()● méthodes : get_correct_number(self)● arguments des méthodes et fonctions :
get_correct_number(random=False)● variables : number =
my_object.get_correct_number()● constantes : ANSWER_TO_LIFE = 42
Conventions de nommage
● Script PEP 8● autre
Pour vérifier
Sources
● http://sametmax.com/cours-et-tutos/les-articles-pour-apprendre-python-dans-le-bon-ordre/
● http://docs.python-guide.org/en/latest/● http://antrix.net/static/pages/python-for
-java/online/● http
://stackoverflow.com/questions/1052435/moving-from-java-to-python
Pour bien commencer
● http://sametmax.com● http://www.talkpythontome.com/● http://pycoders.com/
Pour se tenir au courant
• VIDEO PYCON 2015
Questions
#python #bzhcmp
@__pad__