De ce Python pentru chestii serioase?

Sunt curios, de ce Python? Nu mi s-a părut niciodată un limbaj pentru chestii serioase, ci cel mult pentru prototipizare. Am văzut că e instabil (în sensul că mereu apar API breakage-uri între versiuni) şi nici nu străluceşte la capitolul performanţă.

3 Likes

dau cateva exemple de ce eu am migrat pe python

  • e mult mai succint in exprimare, scrii in cateva linii ce altii exprima in alte limbaje (ex java) in cateva pagini
  • performanta nu e un bottleneck, python3 e mai mult decat decent pt vasta majoritate a nevoilor
  • are librarii f bune pt interactiunea cu filesystemul,
  • se preteaza la absolut orice ai nevoie intr-un pipeline, inlocuieste cu maxim succes bash
  • il gasesti preinstalat peste tot
  • pytest e genial pt scrierea de teste, vine cu tmpdir care te ajuta sa scrii exact ce teste ai nevoie folosind un filesystem temporar, cu un api minimalist si f cuprinzator
  • monkeypatch e un dar trimis de dumnezeu pe pamant sa poti face cu adevarat mocking la runtime
  • e un limbaj oop in acord cu felul in care a gandit Alan Kay, nu class-oriented ca java and company

toate astea inainte sa zicem “data science” unde e standardul de facto

12 Likes

Îmi cer scuze faţă @patkoscsaba că îi poluez topicul, dar probabil cei interesaţi oricum o să-l contacteze în privat :slight_smile:

@tekkie: spre ruşinea mea, n-am auzit de Alan Kay până astăzi. Poţi să detaliezi un pic cum anume e OOP-ul din Python faţă de cele class-oriented? Nu am studiat Python niciodată, nu prea mă ating de limbaje care au sintaxă mult diferită de C++, mi se par bizare şi greu de citit (prefer curly braces languages).

EDIT: m-am uitat acum prin documentaţie,mi se pare că în Python se face OOP ca în toate celelalte limbaje, doar că e sintaxa aia dezlânată :slight_smile: Bănuiesc că “init” este constructorul.

class Dog:

    def __init__(self, name):
        self.name = name
        self.tricks = []    # creates a new empty list for each dog

    def add_trick(self, trick):
        self.tricks.append(trick)

Disclaimer: Nu am fost implicat direct in decizia de migrare pe Python, asa ca redau povestea asa cum am inteles-o eu.

Hmm … in cazul nostru migrarea catre Python era cumva conjuncturala. Proiectul cel vechi, si in continuare cel mare si principal, a fost initial facut pe PHP.
Natura proiectului necesita multa interactiune cu un system de operare tip Unix. Aici ma refer atat la interactiune simpla cu comenzi, cum si interactiuni complexe cu sistemul de fisiere de pe servere. Daca dati o tura pe la http://syneto.eu veti vedea ca de fapt e vorba de virtualizare si management de date.
In acest context, cu cat functionalitatile au devenit mai avansate, am constatat 2 lucruri:

  1. Python are mult mai multe librarii pentru acest lucru, si trecand pe Python vom putea renunta la o mare parte din codul intretinut de noi. Cu alte cuvinte, un cod mai simplu va interactiona mai bine cu ce avem noi “dedesubt”.
  2. Este foarte dificil sa gasesti programatori JavaScript, TypeScript sau PHP care sa aiba si cunostinte mai avansate de systeme de operare, sau sa fie dornici sa le invete. De cele mai multe ori, aplicatiile in aceste limbaje sunt strict orientate spre web si baze de date. Atat.

Acum, cand vine vorba de aplicatii complexe care trebuie sa orchestreze lucruri de genul “Citeste schimbarile de blocuri de pe un disc virtual din VMware, fa un backup ZFS la ele, trimite-l prin retea pe un alt server sau cloud, toate astea respectand anumite SLAs de replicari si protectii de date”, Python devine alegerea naturala.

Iar cand ai o echipa de doar vreo 15-20 programatori, un proiect complex, si 4-5 limbaje de programare diferite, trebuie sa te intrebi daca nu cumva Python e potrivit si pentru partea de web/baza de date? Daca nu cumva vechiul proiect PHP poate fi trimis in pensie si rescris in Python?

Cu un coleg de al meu, Cosmin, in ultimele 3 zile am luat un microserviciu scris in TypeScript si rulat pe Node si l-am mutat pe Python. Am inceput de la “Cum faci o clasa in Python?”, prin “Ce este un dictionar?”, "Cum facem unit teste? - noua ne-a placut mai mult modulul unittest care vine cu Python, chiar daca am incercat si PyTest.
Proiectul, mic cat era, a fost refacut complet, pe Flask, cu unit teste si teste de system complete, cu clase, si static typing.
Cu alte cuvinte, desi am invatat multe, trecerea pe Python, de la TypeScript a fost una destul de usoara. Ca si cantitate de cod, tot pe acolo am iesit.
Si Dumnezeu sa-i binecuvanteze pe cei da la JetBrains ca au creat IntelliJ IDEA. Altfel ma sinucideam sa fac toate identarile din tastatura in Python.

6 Likes

@serghei Uite aici o clasa din proiectul nostru. Noua ne place mai mult codul expresiv, si static typing.

from typing import List, Any
from mailjet_rest import Client

from src.AppConfig import AppConfig
from src.Email.Provider import Provider
from src.Email.Entity import Entity as Email


class MailJetProvider(Provider):
    __app_config: AppConfig
    __mailjet: Client

    def __init__(self, app_config):
        self.__app_config = app_config
        self.__mailjet = Client(auth=(
            self.__app_config.config['mail']['api_public_key'],
            self.__app_config.config['mail']['api_secret_key']
        ), version='v3.1')

    def send(self, email: Email) -> None:
        Provider._prepare_body(email)
        data: dict = {
            'Messages': [
                {
                    'From': {
                        'Email': email.from_,
                        'Name': email.from_name
                    },
                    'To': self._convert_emails_string_to_array(email.to),
                    'Cc': self._convert_emails_string_to_array(email.cc),
                    'Bcc': self._convert_emails_string_to_array(email.bcc),
                    'Subject': email.subject,
                    'HTMLPart': email.body,
                }
            ]
        }

        result: Any = self.__mailjet.send.create(data=data)
        print(f'{result.status_code} {result.json()}')

    @staticmethod
    def _convert_emails_string_to_array(emails: str) -> List[dict]:
        email_list: List[dict] = []

        if emails is not None:
            for email in emails.split(','):
                email_list.append({
                    'Email': email.strip()
                })

        return email_list

La mine se foloseste la automatizare plus tot felul de nebunii in OpenStack. Pe un proiect sunt niste colegi care au facut provizionare automata a echipamentelor telecom

Iti vine server-ul, trantesti pe el imaginea plus configurari. Totul automat.

Plus alte mici scripturi facute de mine pt diverse treburi pe server.

PS: Stie ordinea operatiilor. M-am invatat sa deschid python in bash si sa fac calculele acolo :grin:

Aha, am înţeles motivaţia. Probabil dacă te apuci să cauţi un programator PHP care cunoaşte fineţurile sistemului de operare, e ca şi cum ai căuta acul în carul cu fân.

Mie dacă mi s-ar fi dat tema de a găsi un limbaj scriptabil care să se preteze la interacţiuni complicate cu sistemul de operare probabil m-aş gândi instant la Perl. Deşi în teorie a fost gândit pentru procesare de text, nu cred că există vreun lucru pe care Perl să nu-l poată face. Plus că e “curly braced” şi poate fi şi enervant de concis :slight_smile:

1 Like

Yeah. Avem bucatele scrise si in Perl, de acu vreo 7-10 ani. Nu stiu ce sa zic, cumva nu aprins.

O fi din cauză ca OOP-ul din Perl nu e chiar OOP-ul cu care sunt noi obişnuiţi, definirea claselor se face într-un mod bizar (a class is a package).

EDIT: aah, şi uneori poate fi enervant de criptic, de genul my ($class,$args) = @_, tot timpul trebuie să fac un efort să-mi amintesc chestii de genul “ce naiba e @_”.

Mi se pare un skill indispensabil chiar pt programatorii PHP care se numesc seniori. Cel putin eu asta i-am invatat pe toti care mi-ai trecut prin mana, “prima data linux, apoi php chior, apoi frameworkuri”. Evident ca “programatorii laravel” sau mai rau “programator wordpress” nu au cum face asta. Dar nu e ac in carul cu fan, eu am lucrat cu multi PHPisti care stiau toate astea.

Perl e ‘write only’. Problema e ca poti sa scrii aceeasi chestie intr-un miliard de feluri, destul de criptic. Ca urmare cand te uiti peste cod e mai dificil sa-l descifrezi.

1 Like

Well, PHP este consacrat pentru dezvoltare de aplicaţii web (probabil sunt unul dintre puţinii leneşi care îl folosesc ca limbaj de scripting), nu sunt foarte convins că unui developer obişnuit îi foloseşte la ceva să ştie ce-i ăla socket_bind, probabil majoritatea nici n-au auzit de funcţia asta.

2 Likes

Da, bine spus “write only” :slight_smile: Faptul că poţi să scrii acelaşi lucru într-o mie de feluri te face să nu-ţi înţelegi propriul cod, după o perioadă de timp.

Dar ca ecosistem, Perl probabil e unul dintre cele mai bogate şi variate, orice ai nevoie, cineva a scris deja un modul (sau mai multe).

Motivul numarul 1 e ca e usor de invatat.
Ca urmare e cunoscut de o gramada de oameni care nu sunt neaparat orientati pe programare.

Motivul numarul 2 e acelasi ca la alte jafuri de limbaje de programare, cum ar fi Java sau C#:
Nu e limbajul in sine ce confera avantajul principal, ci ecosistemul. Bibliotecile, IDEurile, etc.

in compania din care fac parte, in echipa de Data Science s-a facut trecerea de la R la Python :crazy_face: Cred ca pe langa Java, acopera cam orice domeniu al programarii.

Sincer cred ca ai fost intr-o bula :slight_smile:

Am folosit JS ptr. diverse proiecte mici/medii. Apoi am folosit Python ptr. acelasi gen de proiecte. Viteza de implementare este semnificativ mai mare cu Python, usor de intretinut, usor de invatat librariile necesare, etc.
Acum vreo cativa ani am citit ca Eric S. Raymond a recomandat python ptr. usurinta de dev (parca a scris un program de mail reading in cateva linii de cod). O fi stiut el ceva.

Pai e core Python contributor… “In July 2000 I was given write access to the Python CVS repository, and am now officially a co-developer of the language.” sursa

Se face data science in java pe undeva?

1 Like

Vreau sa fac o remarca (,) constructiva, sper sa-mi iasa. Cred ca in cativa ani codul pus de tine va arata un pic altfel, mai pythonic :innocent: si poate mai putine chestii care incep cu _

Si eu cand am trecut pe python lucram “non-pythonic”. Am tinut-o asa cam jumatate de an, dar stateam mult pe youtube si plecam urechea la cei care o tot dadeau inainte cu pythonic. Incet-incet codul meu a devenit tot mai lacunar, acum scriu f minimalist, am descoperit puterea tuplelor (acum cativa ani eram clar Toma necredinciosul legat de ele), sunt multe de zis.

De asemenea am format un grupulet de librarii care ma lasa sa fac multe lucruri by default, de ex DTO-urile cu pydantic pt ca imi da validare by default, lucrez cu adnotari de deprecare (desi nu sunt in core), pytest-bdd, si tot asa.

Revenind la titlul topicului, nu sunt convinsa ca cel mai rapid travel website din state pe care l-am facut acum 10 ani in PHP (si inca merge ca uns), si care a pus in cap payment providerul Chase pt ca ducea prea mult trafic… ei bine n-as avea curaj sa il fac in Python. Nici macar cu microservicii si lambda functions si ce mai vreti voi si e acuma trendy. Sunt unele chestii in Python care nu iti dau aceasta incredere, in schimb PHP “cu ochii inchisi” vorba aia, nu e nevoie de mai mult de 2-3 oameni din bula de care zicea @IceRidder ca sa il scrii cu atentie la detaliile care fac diferenta.

1 Like

Eu as fi folosit Go sau C++. Dar probabil nu sunt multi programatori de Go sau C++.

Si, din partea noastra, a programatorilor PHP, stim de socket, de fork, de semafoare, de pipes sau de fire de executie.