Avez-vous déjà pensé qu'un jour vous étiez entré trop rapidement dans la programmation Web PHP?
Plusieurs années se sont déjà écoulées, vous avez acquis beaucoup d'expérience et vous ne pouvez pas penser à d'autres façons de travailler avec le Web que PHP. Peut-être, vous doutez parfois du choix que vous avez fait, mais n'êtes pas en mesure de confirmer vos doutes ici et maintenant. En même temps, vous avez besoin d'exemples réels; vous voulez comprendre les changements qui peuvent survenir dans certains aspects de votre travail.
Aujourd'hui, je vais essayer de répondre à la question suivante: "
Et si nous utilisons Python au lieu de PHP? ".
J'ai moi-même posé cette question plusieurs fois. J'utilise PHP depuis 11 ans déjà et je suis un spécialiste PHP certifié. Je l'ai maîtrisé donc cela fonctionne exactement comme je le souhaite. J'ai été vraiment intrigué par plusieurs articles qui critiquaient sévèrement
PHP (
PHP: une fractale de mauvaise conception ). Cependant, quand le hasard est venu, je suis passé à Ruby puis à Python. Finalement, j'ai choisi ce dernier. Maintenant, je vais essayer d'expliquer comment nous, les gars de Python, vivons là-bas.

Format de l'article
La meilleure façon d'apprendre une nouvelle langue est de la comparer à une langue que vous pouvez déjà appliquer, sauf si la nouvelle langue diffère radicalement de la langue actuelle. Un article sur le portail Web Ruby (
Ruby d'autres langues ) fournit une telle comparaison, mais il manque d'exemples.
Je dois également noter que cet article ne compare que les aspects qui attirent votre attention au cours des premières semaines après le passage à la nouvelle langue.
Préparation des consoles
J'ai fait de mon mieux pour rendre cet article interactif. Par conséquent, je recommande d'exécuter tous les exemples dans les consoles lors de la lecture de l'article. Vous aurez besoin d'une console PHP, ou vous pouvez utiliser la console
PsySH , ce qui est encore mieux:
php -a
Et une console Python. Je recommande d'utiliser
bpython ou
ipython , car ils proposent déjà une comparaison d'achèvement de code avec la console par défaut intégrée dans le langage. Cependant, l'option suivante est également applicable:
python
Et puis:
import rlcompleter import readline readline.parse_and_bind("tab: complete")
Éviter la répétition de ces actionsCréez un fichier ~ / .pyrc avec:
import rlcompleter import readline readline.parse_and_bind("tab: complete")
Ajoutez quelques lignes dans le fichier ~ / .bashrc:
export PYTHONSTARTUP="${HOME}/.pyrc" export PYTHONIOENCODING="UTF-8"
Adn pour apporter des modifications immédiatement sans se reconnecter:
source ~/.bashrc
À propos des langues
- Python est un langage qui présente un typage dynamique de canard fort ( consultez Informations sur la dactylographie ). Python n'est pas limité en termes d'application. Il est utilisé pour le développement web, les démons, les calculs scientifiques ou comme langage d'extensions. Langues similaires en termes de frappe: Ruby.
- PHP est un langage qui propose une frappe dynamique de canard faible. PHP est également un langage courant, mais son domaine d'application couvre principalement le Web et les démons. D'autres fonctionnalités ne sont pas correctement définies, ce qui la rend inapplicable en production. Certaines personnes croient que PHP est destiné à mourir . Langages similaires en termes de frappe: JavaScript, Lua, Perl.
Spécificités générales
- Le code est écrit dans des fichiers .py quelle que soit la version de Python. Aucune balise d'ouverture comme <? PHP n'est requise, car Python a été initialement développé comme langage de programmation à usage général.
- De plus, il n'y a pas de php.ini pour la même raison. Il y en a deux douzaines
variables d'environnement , mais elles ne sont pas définies dans la plupart des cas (à l'exception de PYTHONIOENCODING). En d'autres termes, il n'y a pas de connexions par défaut aux bases, à la gestion des filtres d'erreur, à la gestion des limites, aux extensions, etc., ce qui est naturel pour la plupart des langages à usage général. Par conséquent, les programmes se comportent de manière similaire dans la plupart des cas (leur comportement ne dépend pas des paramètres préférés de votre chef d'équipe). Dans la plupart des cas, des paramètres tels que php.ini sont stockés dans le fichier de configuration principal d'une application. - Un point-virgule n'est pas nécessaire à la fin d'une chaîne. Cependant, si nous y mettons un point-virgule, cela fonctionne comme en PHP. Néanmoins, il est inutile et indésirable, vous pouvez donc simplement l'oublier.
- Les variables ne commencent pas par $ (dont PHP a hérité de Perl qui à son tour l'a adopté
de Bash). - L'affectation en cycles et conditions ne s'applique pas, de sorte que personne ne se trompe de comparaison pour l'affectation, ce qui est une erreur courante (comme le pense l'auteur de la langue). Voir PEP 572 pour python 3.8 si vous en avez besoin.
- Lors de l'analyse des fichiers, Python place automatiquement la copie du fichier avec l'extension .pyc (à condition que votre version Python soit inférieure à 3,3 et que vous n'ayez pas installé PYTHONDONTWRITEBYTECODE ) dans le même dossier que votre code d'octet. Ensuite, il exécute toujours ce fichier, sauf si vous changez la source.
Ces fichiers sont automatiquement ignorés dans tous les IDE et n'interfèrent généralement pas. Cette fonctionnalité peut être perçue comme un analogue complet de PHP APC, étant donné que les fichiers .pyc seront probablement situés dans la mémoire cache du fichier. - Au lieu de NULL, TRUE, false, nous devons utiliser None, True, false (en particulier dans ce cas).
Imbrication et retrait
Voici quelque chose d'inhabituel: l'imbrication de code est déterminée avec des retraits au lieu de crochets.
Donc, au lieu de:
foreach($a as $value) { $formatted = $value.'%'; echo $formatted; }
Nous devons écrire ce qui suit:
for value in a: formatted = value + '%' print(formatted)
Attendez, attendez! Ne fermez pas l'article. Ici, vous pourriez faire l'erreur même que j'ai commise.
Une fois, j'ai cru que l'idée d'utiliser des retraits pour l'imbrication de code était ridicule. Ma nature entière protestait contre cela, car tous les développeurs écrivent leur code à leur manière, indépendamment des différents guides de style.
Voici le mystère du monde: il n'y a pas de problème de retrait. Dans la plupart des cas (99% des cas), les retraits sont placés automatiquement par IDE comme dans toute autre langue. Vous n'y pensez pas du tout. Je n'ai rencontré aucun problème lié aux retraits de plus de 2 ans d'utilisation de la langue.
Typage fort
La prochaine chose à laquelle vous devez faire attention est le typage fort. Cependant, certains codes d'abord:
print '0.60' * 5; print '5' == 5; $a = array('5'=>true); print $a[5]; $value = 75; print $value.'%'; $a='0'; if($a) print 'non zero length';
Tous les exemples ci-dessus sont possibles grâce à la frappe dynamique.
Oui, je sais que la déclaration de type est disponible pour PHP. Mais il n'est pas activé par défaut et ne fonctionne pas partout.
Cependant, les éléments suivants ne fonctionneront pas en Python:
>>> print "25" + 5 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: cannot concatenate 'str' and 'int' objects
Habituellement, les types de données ne seront pas mélangés dans votre code et cet effet ne vous distraira pas. En général, lorsque j'ai codé sur PHP, il n'y avait que quelques situations par projet où la frappe dynamique a vraiment aidé. Dans tous les autres cas, des variables du même type interagissaient entre elles.
Le typage fort affecte la gestion des erreurs. Par exemple, si une fonction
int renvoie un entier, elle ne peut pas retourner
None à une chaîne dont ce type ne peut pas être extrait explicitement. Dans ce cas, une exception sera levée. Cela peut nécessiter la conversion de toutes les données de l'utilisateur dans le type de données requis, sinon une exception sera levée un jour dans la version Production.
try: custom_price = int(request.GET.get('custom_price', 0)) except ValueError: custom_price = 0
Il affecte non seulement les fonctions standard, mais également certaines méthodes des listes, des chaînes et certaines fonctions de bibliothèques supplémentaires. Habituellement, un développeur Python garde à l'esprit toutes les exceptions qui peuvent être déclenchées et les considère. Si le développeur ne s'en souvient pas, il vérifie le code de la bibliothèque. Bien sûr, parfois, tous les cas ne sont pas pris en compte et les utilisateurs peuvent provoquer des exceptions dans la version Production. Comme il s'agit d'un phénomène rare et que les frameworks Web les envoient généralement automatiquement au courrier de l'administrateur, de tels cas sont rapidement résolus.
Afin d'utiliser des valeurs de différents types de données dans une même expression, elles doivent être converties. Il y a des fonctions pour cela:
str ,
int ,
bool ,
long . En outre, il existe des décisions plus pratiques pour le formatage.
Cordes
Formatage
En PHP:
$this_way = 'this_way'; echo "Currently you do it $this_way or {$this way}."; echo "Or ".$this_way."."; echo sprintf("However the following is possible: , %s or %1$'.9s.", $this_way);
Maintenant, vous devez apprendre à le faire d'une manière différente:
etot = 'this' var = 'option' print('To %s option' % etot) print(etot + ' option can also be used, but not recommended) print('Or to %s %s' % (etot, var)) print('Or to %(etot)s %(var)s' % {'etot': etot, 'var': var}) # Very useful for localization team print('Or to {} {}'.format(etot, var)) print('Or to {1} {0}'.format(var, etot)) print('Or to {etot} {var}'.format(var=var, etot=etot)) # And finally print(f'Or to {etot} {var}') # Starting from Python 3.6
Il y a plus d'options et il y a une option pratique pour les localisations.
Méthodes de chaîne
Python a quelque chose qui manque dans PHP: les méthodes intégrées. Comparons:
strpos($a, 'tr'); trim($a);
vs a.index('tr') a.strip()
Et à quelle fréquence faites-vous quelque chose comme ça?
substr($a, strpos($a, 'name: '));
vs a[a.index('name: '):]
Prise en charge Unicode
Enfin, Unicode. En Python 2, toutes les chaînes ne sont PAS Unicode par défaut. (En Python 3, toutes les chaînes sont Unicode par défaut). Cependant, lorsque vous ajoutez le caractère
u au début d'une chaîne, il devient automatiquement Unicode. Et puis toutes les méthodes de chaîne intégrées (et non intégrées) de Python fonctionneront correctement.
>>> len(' ')

En PHP, le traitement Unicode naturel se développait pour PHP 6 mais PHP 6 a été annulé ( Andrei Zmievski: ce qui est arrivé à Unicode et PHP 6 ).
En PHP, au fait, vous pouvez utiliser la surcharge de la fonction MBString pour recevoir un effet similaire mais il est obsolète.
Cependant, vous ne pourrez pas travailler avec des chaînes binaires en utilisant des fonctions surchargées, mais vous pourrez toujours travailler avec une chaîne en tant que tableau.
À propos des chaînes brutes (facultatif)Chaînes brutes
Vous devez connaître la différence entre les chaînes entre guillemets simples et les chaînes entre guillemets doubles:
$a = 'Hello.\n'; $a[strlen($a)-1] != "\n";
La fonctionnalité similaire en Python a appelé les chaînes brutes. Pour l'utiliser, placez le caractère
r devant la chaîne entre guillemets simples.
a = r'Hello.\n' a[-1] != '\n'
Tableaux
Il est maintenant temps pour les tableaux. En PHP, vous pouvez utiliser des entiers ou des chaînes comme clés:
var_dump([0=>1, 'key'=>'value']);

En PHP, les tableaux ne sont pas des tableaux standard ( listes ), mais des tableaux associatifs ( dictionnaire ). Les tableaux standard sont également disponibles en PHP, ils sont SPLFixedArray . Ils nécessitent moins de mémoire, fonctionnent potentiellement plus rapidement, mais en raison de la complexité de création et d'extension, ils sont rarement utilisés.
En Python, quatre types de données sont utilisés pour un tableau:
- liste
a = [1, 2, 3]
- dict - dictionnaire. Les dictionnaires n'ont aucun ordre de stockage des données (comme ils le font en PHP).
d = {'a': 1, 'b': 2, 'c': 3}
- tuple. Quelque chose comme un tableau fixe de valeurs non homogènes. Parfaitement adapté au retour de plusieurs valeurs d'une fonction et au stockage compact des configurations.
t = (True, 'OK', 200, )
- ensemble. Fondamentalement, il s'agit d'une liste de valeurs uniques qui n'ont aucun ordre de stockage.
s = set([1,3,4]) s[0] = False
En PHP, les tableaux sont une sorte de couteau de l'armée suisse - ils peuvent servir à toutes fins. Quant à Python, vous devez utiliser des tableaux de données natifs pour l'informatique. En outre, vous devez utiliser des tableaux de données appropriés pour chaque cas. Vous pouvez dire que ce sont des difficultés inutiles auxquelles les programmeurs ne devraient jamais faire face. Eh bien, ce n'est pas le but.
- Premièrement: la possibilité de choisir entre tuple, set, list et dict ne rend pas les choses difficiles - cela devient simplement une habitude inconsciente comme changer de vitesse.
- Deuxièmement: la liste ou le dict sont utilisés dans la plupart des cas.
- Troisièmement: dans la plupart des cas, lorsque vous devez stocker la paire clé-valeur, l'ordre n'est pas essentiel, cependant, lorsque vous devez conserver l'ordre, dans la plupart des cas, il n'y a que des valeurs au lieu de paires clé-valeur.
- Quatrièmement: Python a un dictionnaire ordonné - OrderedDict .
Importations
Ceci est une fonctionnalité très intéressante. C'est une sorte de concept alternatif d'espaces de noms qui doivent être utilisés.
En PHP, vous écrivez
require_once et il reste disponible jusqu'à la fin de la session d'exécution PHP. Généralement, lors de l'utilisation de CMS, les développeurs mettent tout en classes, les placent dans des emplacements spéciaux, écrivent une petite fonction qui connaît ces emplacements et enregistrent cette fonction via
spl_autoload_register au début du fichier.
En Python, cependant, chaque fichier a son propre espace de nom. Par conséquent, un fichier ne contiendra que les objets que vous y importez. Par défaut, seule la bibliothèque Python standard est disponible (environ 80 fonctions).
Consultez l'exemple ci-dessous:
Supposons que vous avez créé le fichier
tools / logic.py :
def is_prime(number): max_number = int(sqrt(number)) for multiplier in range(2, max_number + 1): if multiplier > max_number: break if number % multiplier == 0: return False return True
Maintenant, vous voulez l'utiliser dans le fichier
main.py. Dans ce cas, vous devez importer le fichier entier ou les entités de fichier dont vous avez besoin dans le fichier cible sur lequel vous travaillez.
from tools.logic import is_prime print(is_prime(79))
Cette règle s'applique à l'ensemble de Python. Dans la plupart des cas, lorsque vous commencez à travailler sur n'importe quel fichier, vous devez d'abord importer des objets Python auxiliaires dans votre fichier: vos propres bibliothèques et celles intégrées. C'est comme si les fonctions PHP comme mysqli_ *, pdo_ *, memcached_ *, ainsi que tout votre code, étaient stockées dans des espaces de noms et vous devez les importer dans chaque fichier avec lequel vous travaillez. Quels sont les avantages de cette approche?
- Premièrement: différents objets dans différents fichiers peuvent avoir des noms identiques. Cependant, c'est vous qui sélectionnez l'objet, son nom et le fichier cible.
- Deuxièmement: le refactoring est beaucoup plus facile. Vous pouvez toujours garder une trace d'une classe, d'une fonction ou de toute autre entité. Utilisez une simple recherche pour localiser une fonction et voir où / comment elle est utilisée.
- Troisièmement: cette fonctionnalité incite les développeurs à réfléchir à la structure du code (au moins dans une certaine mesure).
En revanche, nous ne pouvons mentionner qu'un seul inconvénient:
les importations circulaires . Cependant, c'est un problème rare. En outre, c'est un problème familier et les développeurs connaissent les moyens de le résoudre.
Est-il pratique d'utiliser tout le temps les importations? Cela dépend de vos préférences. Si vous souhaitez avoir plus de contrôle sur le code, vous préférerez utiliser les importations. Certaines équipes ont même des règles qui régissent l'ordre d'attribution du code externe, afin de minimiser le montant des importations circulaires. Si votre équipe n'a pas de telles règles et que vous ne voulez pas trop vous embêter, vous pouvez simplement compter sur IDE qui importera automatiquement tout ce que vous utilisez. De plus: les importations ne sont pas une fonctionnalité Python unique, elles sont également utilisées en Java et C #.
Il n'y a eu jusqu'à présent aucune plainte.
Paramètres * args et ** kwargs dans une fonction
La syntaxe avec les paramètres par défaut est généralement la même:
function makeyogurt($flavour, $type = "acidophilus") { return "Making a bowl of $type $flavour."; }
vs def makeyogurt(flavour, ftype="acidophilus"): return "Making a bowl of %s %s." % (ftype, flavour, )
Cependant, vous pouvez parfois avoir besoin d'une fonction pour un nombre inconnu d'arguments.
Par exemple, une fonction proxy, une fonction d'enregistrement ou une fonction de réception de signaux. En PHP, à partir de la version 5.6, la syntaxe suivante est disponible:
function sum(...$numbers) { $acc = 0; foreach ($numbers as $n) { $acc += $n; } return $acc; } echo sum(1, 2, 3, 4);
Respectivement, en Python, vous pouvez ajouter des arguments sans nom dans un tableau et ajouter des arguments nommés dans un dictionnaire:
def acc(*args, **kwargs): total = 0 for n in args: total += n return total print(acc(1, 2, 3, 4))
Respectivement,
* args - liste des arguments sans nom,
** kwargs - dictionnaire des arguments nommés.
Cours
Jetez un œil au code ci-dessous:
class BaseClass: def __init__(self): print("In BaseClass constructor") class SubClass(BaseClass): def __init__(self, value): super(SubClass, self).__init__()
Les principales différences avec PHP sont les suivantes:
- self est utilisé à la place de $ this et les méthodes sont toujours appelées à l'aide de l'opérateur d'accès ("."). En outre, «soi» devrait toujours être le premier argument dans toutes les méthodes (enfin, dans la plupart d'entre elles). Le fait est que Python fournit toutes les méthodes avec un lien vers l'objet avec le premier argument (l'objet lui-même peut être ajouté à une variable avec n'importe quel nom).
- Comme en PHP, il existe un analogue des noms magiques . Au lieu de __construct - __init__ . Au lieu de __get - __getattr__ , etc.
- nouveau n'est pas requis. La création d'une instance de classe revient à appeler une fonction.
- Un appel plus complexe à la méthode parent. Quant au super, vous devez toujours garder à l'esprit tous les détails. parent :: Comme pour PHP, la structure est moins volumineuse.
Il convient également de mentionner les éléments suivants:
- Plusieurs classes peuvent être héritées.
- Pas de public , protégé , privé . Python permet de changer une structure d'instance (ainsi que la classe entière) lors de l'exécution via une simple affectation, donc aucune protection n'est nécessaire. Ainsi, la réflexion n'est pas également requise. Cependant, il y a un analogue de l'état protégé - double soulignement avant le nom. Cependant, cette opération change simplement le nom visible de la variable / méthode en _% ClassName% __% varname% qui permet de travailler avec des données cachées.
- Pas de classes statiques, finales et d'interfaces. Le modèle est plus basé sur les objets en Python en général. Au lieu de Singleton, vous aurez probablement un fichier contenant toutes les fonctions requises ou un fichier qui renvoie la même instance lors de l'importation. Au lieu de l'interface, vous créerez probablement une classe qui déclenche des exceptions pour les méthodes qui ne sont pas réaffectées pour une raison quelconque (c'est-à-dire qu'une solution de contournement est possible).
- Il n'est pas souhaité d'appliquer uniquement la programmation orientée objet (POO). Comme tout est de toute façon un objet (même booléen) et que la syntaxe n'a pas d'opérateurs différents pour appeler une méthode ou une fonction à partir d'un fichier importé, tous les appels sont effectués avec l'opérateur d'accès ("."). Ainsi, l'encapsulation ne nécessite pas nécessairement la POO. Par conséquent, dans la plupart des projets, les classes sont créées là où elles sont vraiment nécessaires.
Style de codage
J'ai travaillé sur plusieurs projets à long terme et j'ai remarqué que tous les membres de l'équipe ont un style de codage différent. Dans de nombreux cas, un code peut aider à identifier l'auteur du code. J'ai toujours voulu que n'importe quelle norme de style de code soit adoptée à des fins de cohérence.
Cependant, il y a toujours eu de nombreux arguments lors de l'approbation de ce document au sein de l'équipe. Ce problème affecte également Python, mais dans une moindre mesure, car il existe plusieurs recommandations de spécialistes qualifiés, qui seront certainement suffisantes pour commencer:
En outre, il existe un soi-disant Zen de Python. Une de ses règles stipule qu '"il devrait y avoir une - et de préférence une seule - la manière précédente de le faire". Ainsi, un code ne peut pas être écrit de plusieurs manières approximativement similaires. Bien sûr, c'est de l'idéalisme, mais cela aide dans de nombreux cas:
- Au lieu d'une grande bibliothèque de stock contenant plusieurs fonctions qui se dupliquent partiellement, nous utilisons un plus petit ensemble de méthodes et des bibliothèques d'intégration supplémentaires (par exemple pour les totaux de hachage).
- Au lieu de strlen et count , nous utilisons toujours len .
etc.
Versions Python
Les nouvelles versions de PHP sont toujours rétrocompatibles avec les précédentes, bien que des améliorations soient parfois nécessaires. Par contre, il y a Python 2 et Python 3 Ils sont peu compatibles par défaut. Cependant, récemment, les développeurs Python ont considérablement amélioré la situation. Vous pouvez écrire un code pour deux versions de Python, mais si vous utilisez de nouvelles fonctionnalités Python 3 comme la programmation asynchrone ou de nouvelles fonctionnalités Unicode (UTF 8), vous rencontrerez probablement des difficultés. Pour cette raison, les projets qui ont déjà été développés et codés depuis plusieurs années utilisent toujours Python 2.
Mais pour les nouveaux projets, il n'y a aucune raison d'utiliser Python 2.
Alias multilingues
Vous trouverez ci-dessous la liste des mots clés qui expliquent l'alternative que Python fournit à la technologie que vous utilisez actuellement.
- compositeur -> pip
- mod_php -> mod_wsgi
- nginx + php-fpm -> nginx + uwsgi + uwsgi_python
- daemon.io -> tornade, torsadée
- Framework Zend -> Django
- Phalcon -> faucon
Conclusion
Comment savez-vous si vous en avez besoin ou non?
- Vous pensez que plus la frappe est forte, mieux c'est.
- Vous préférez un langage qui présente une architecture bien organisée.
- Vous êtes perfectionniste, une diversité excessive vous agace.
- Les postes de travail Python dans votre ville semblent plus prometteurs (ou vous vous ennuyez de développer uniquement des portails Web).
- Vous souhaitez que votre langage de programmation principal soit adapté au développement de tout type de logiciel (compte tenu des restrictions raisonnables liées à la frappe dynamique).
- Vous n'aimez pas le niveau de compétence des développeurs juniors (en raison de la courbe d'apprentissage relativement faible).
Ma façon d'apprendre Python
Si vous êtes un développeur expérimenté, vous aurez besoin de jusqu'à trois semaines pour l'apprendre sans faire trop d'efforts.
- Première semaine : lisez Dive Into Python , chapitres 2-7. Vous pouvez parcourir brièvement les autres chapitres, en faisant attention aux points intéressants uniquement. Dans le même temps, effectuez 10 tâches avec Project Euler . Enfin, créez un utilitaire de console qui accepte les paramètres. Vous pouvez soit porter n'importe lequel de vos scripts bash précédents, soit créer un analogue de ls à partir de BusyBox , ou quelque chose de nouveau. Le fait est que le script doit faire quelque chose d'utile, quelque chose que vous faites fréquemment. Par exemple, j'ai porté mon utilitaire PHP qui peut afficher des données dans le cache mémoire.
- Deuxième semaine : Créez un simple analogue de Medium dans Django et gun sur n'importe quel hébergement. Faites attention aux composants: enregistrement, connexion, récupération de mot de passe, partage de messages et de commentaires et suppression, vérification des autorisations pour les actions.
- Troisième semaine : Sélectionnez une entreprise pour laquelle vous souhaitez travailler, envoyez-leur votre CV en demandant une tâche de test Python pour tester vos compétences.
Bonne chance!