python après 15 ans de java

52
BreizhCamp 2015 #BzhCmp #python #bzhcmp BreizhCamp 2015 #BzhCmp Python après 15 ans de JAVA Pierre-Alban DEWITTE - @__pad__

Upload: pierre-alban-dewitte

Post on 03-Aug-2015

93 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Python après 15 ans de JAVA

BreizhCamp 2015

#BzhCmp

#python #bzhcmp

BreizhCamp 2015

#BzhCmp

Python après 15 ans de JAVA

Pierre-Alban DEWITTE - @__pad__

Page 2: Python après 15 ans de JAVA

dev.myscript.com

Page 3: Python après 15 ans de JAVA
Page 4: Python après 15 ans de JAVA

PYTHON

Page 5: Python après 15 ans de JAVA

● Langage généraliste● Dynamiquement typé● Orienté objet● Fonctionnel● Gestion de la mémoire par un garbage

collector

PYTHON

Page 6: Python après 15 ans de JAVA

● 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

Page 7: Python après 15 ans de JAVA

Python 2 ou Python 3

Page 8: Python après 15 ans de JAVA

● 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)

Page 9: Python après 15 ans de JAVA

● Contraint par l’environnement● Contraint par des librairies

http://python3wos.appspot.com/ et notamment Spark

● Vous voulez utiliser Jython

Pourquoi choisir Python 2

Page 10: Python après 15 ans de JAVA

Le langage

Page 11: Python après 15 ans de JAVA

● Bye bye les accolades !● Ne pas mélanger espaces et

tabulations

Identation

Page 12: Python après 15 ans de JAVA

• 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')

Page 13: Python après 15 ans de JAVA

● 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

Page 14: Python après 15 ans de JAVA

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)

Page 15: Python après 15 ans de JAVA

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)

Page 16: Python après 15 ans de JAVA

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

Page 17: Python après 15 ans de JAVA

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

Page 18: Python après 15 ans de JAVA

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']

Page 19: Python après 15 ans de JAVA

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'}

Page 20: Python après 15 ans de JAVA

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=(',', ': ')))

Page 21: Python après 15 ans de JAVA

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" ]}

Page 22: Python après 15 ans de JAVA

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 ?')

Page 23: Python après 15 ans de JAVA

Fonctions

########### appel 1 ###########arg1: 1arg2: defaultargs: ()kwargs: {}

########### appel 2 ###########arg1: 2arg2: laargs: ('declaration', 'est', 'tres', 'flexible')kwargs: {'pensez': 'quoi ?', 'vous': 'en'}

Page 24: Python après 15 ans de JAVA

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

Page 25: Python après 15 ans de JAVA

● Favoriser autant que possible l’utilisation de fonctions

● Toujours préférer une fonction à l’utilisation de l’héritage

Classes et fonctions

Page 26: Python après 15 ans de JAVA

● 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

Page 27: Python après 15 ans de JAVA

Et vraiment beaucoup de choses

Page 28: Python après 15 ans de JAVA

Eco-système

Page 29: Python après 15 ans de JAVA

● De nombreuses librairies sont disponibles dans le runtime Python

● Eco-système très riche et très communautaire

Librairies

Page 30: Python après 15 ans de JAVA

Librairies natives

Page 31: Python après 15 ans de JAVA

Jetty <> http.server

python –m http.server 8080

● Utile créer un serveur HTTP minimaliste

Page 32: Python après 15 ans de JAVA

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

Page 33: Python après 15 ans de JAVA

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')

Page 34: Python après 15 ans de JAVA

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

Page 35: Python après 15 ans de JAVA

● 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')

Page 36: Python après 15 ans de JAVA

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" ]}

Page 37: Python après 15 ans de JAVA

Autres équivalences

JAVA PYTHONCommons IO os, shutil,

subprocess et sysCommons Collections

collections

Commons Codec codecsGuava Ba y’en a pas

besoin

Page 38: Python après 15 ans de JAVA

Gestion des dépendances

Page 39: Python après 15 ans de JAVA

● 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

Page 40: Python après 15 ans de JAVA

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

Page 41: Python après 15 ans de JAVA

Librairies disponibles dans PyPi

Page 42: Python après 15 ans de JAVA

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

Page 43: Python après 15 ans de JAVA

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● …

Page 44: Python après 15 ans de JAVA

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 …

Page 45: Python après 15 ans de JAVA

● 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

Page 46: Python après 15 ans de JAVA

PEP8

Page 47: Python après 15 ans de JAVA

● 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

Page 48: Python après 15 ans de JAVA

● Script PEP 8● autre

Pour vérifier

Page 49: Python après 15 ans de JAVA

Sources

Page 51: Python après 15 ans de JAVA

● http://sametmax.com● http://www.talkpythontome.com/● http://pycoders.com/

Pour se tenir au courant

• VIDEO PYCON 2015

Page 52: Python après 15 ans de JAVA

Questions

#python #bzhcmp

@__pad__