Hacker News

Python motako egiaztatzaileen konparaketa: edukiontzi hutsaren inferentzia

Iruzkinak

10 min read Via pyrefly.org

Mewayz Team

Editorial Team

Hacker News

Ontzi hutsek zergatik hausten duten Python motako zuzentzaileak — eta zer egin dezakezu horri buruz

Python-en pixkanakako idazketa-sistema nabarmen hazi da PEP 484-k 2015ean mota-aholkuak sartu zituenetik. Gaur egun, milioika garatzailek motaren egiaztatzaile estatikoetan oinarritzen dira akatsak harrapatzeko produkziora iritsi aurretik. Baina bada mota-sistemaren txoko sotil eta frustragarri bat, oraindik ere esperientziadun ingeniariak ere ibiltzen dituena: zer mota du edukiontzi huts batek? x = [] oharrik gabe idazten duzunean, zure mota-zuzentzaileak asmatu behar du, eta zuzentzaile ezberdinek desberdin asmatzen dute. Dibergentzia honek benetako arazoak sortzen ditu kode-oinarri handiak mantentzen dituzten taldeentzat, non mota-zuzentzaileak aldatzeak edo konbinatzeak ustekabeko ehunka akats azalera ditzake egun batetik bestera.

Artikulu honek Python motako lau egiaztatzaile nagusiek (mypy, pyright, pytype eta pyre) edukiontzi hutsen inferentzia nola kudeatzen duten azaltzen du, zergatik ez dauden ados eta zein estrategia praktiko har ditzakezun mota segurua den Python idazteko, tresnaren aukera edozein dela ere.

Oinarrizko arazoa: ontzi hutsak berez anbiguoak dira

Kontuan izan Python-en lerro inozo hau: emaitzak = []. emaitzak zerrenda[int] al dira? zerrenda[str]? Zerrenda bat[dik[str, Edozein]]? Testuinguru gehigarririk gabe, ez dago benetan jakiteko modurik. Python-en exekuzio-denborak ez du axola —zerrendak heterogeneoak dira berez—, baina motako zuzentzaile estatikoek mota konkretu bat esleitu behar diote aldagai bakoitzari beren lana egiteko. Horrek oinarrizko tentsioa sortzen du Python-en malgutasun dinamikoaren eta analisi estatikoak ematen saiatzen diren bermeen artean.

Arazoa hiztegiekin eta multzoekin konposatzen da. {} huts bat dikta gisa analizatzen da, ez multzo gisa, eta horrek anbiguotasun sintaktikoa gehitzen du mota-mailako anbiguotasunari. Eta habiaraturiko edukiontziak — pentsa defaultdict(zerrenda) edo results = {k: [] for k teklatan - inferentzia motorrak beren mugetara bultzatzen dituzte. Mota egiaztatzaile bakoitzak bere heuristika garatu du, eta desberdintasunak garatzaile gehienek uste dutena baino esanguratsuagoak dira.

Benetako lan-kargak prozesatzen dituzten produkzio-sistemetan (bezeroen erregistroak kudeatzen dituen CRM bat, lerro-elementuak sortzen dituen fakturazio-modulu bat edo analisi-bideen batuketa-neurriak) edukiontzi hutsak etengabe agertzen dira hasierako eredu gisa. Haien motak gaizki hartzeak ez du linter abisuak soilik sortzen; exekuzio garaira igarotzen diren benetako akatsak ezkuta ditzake.

Mypy: Inferentzia geroratua edozein inplizituarekin

Mypy-k, Python motako egiaztatzailerik zaharrena eta erabiliena, ontzi hutsen ikuspegi nahiko leuna hartzen du. Funtzio-esparruan x = [] aurkitzen duenean, motaren erabakia atzeratzen eta elementu-mota ondorengo erabileratik ondorioztatzen saiatzen da. x = [] eta ondoren x.append(42) idazten baduzu, mypy-k list[int] ondorioztatuko du. "Batu" estrategia honek harrigarriro ondo funtzionatzen du edukiontzia esparru berean beteta dagoen kasu zuzenetarako.

Hala ere, mypy-ren portaera izugarri aldatzen da testuinguruaren eta zorroztasun-ezarpenen arabera. Moduluaren esparruan (goi-mailako kodea), edo edukiontzia bete aurretik beste funtzio batera pasatzen denean, mypy maiz zerrenda[Edozein]era itzultzen da. --strict markapean, honek errore bat abiarazten du, baina modu lehenetsian isilean pasatzen da. Horrek esan nahi du modu zorrotzik gabe mypy exekutatzen duten taldeek inplizituki idatzitako dozenaka ontzi pila ditzaketela mota-sistematik ihes-estotila gisa jarduten dutenak, bere helburua gaindituz.

Jokaera bereziki sotil bat: 0.990 baino lehenagoko mypy bertsioek batzuetan zerrenda[Ezezaguna] barnetik ondorioztatuko lukete eta gero zerrenda[Edozein]era zabalduko dute esleipenean. 0.990 osteko, inferentzia zorroztu egin zen, baina aldaketak mundu errealeko kode-oinarri harrigarri bat hautsi zuen, konturatu gabe jokabide permisiboan oinarritzen zirenak. Hau errepikatzen den gaia da: edukiontzi hutsaren inferentziaren aldaketak mota-zuzentzaileen eguneratzerik kaltegarrienetakoak dira, ereduak oso nonahikoak direlako.

Pyright: Inferentzia zorrotza eta "Ezezaguna" mota

Pyright-ek, Microsoft-ek garatua eta Pylance VS Code-n bultzatzen duena, jarrera filosofiko oso desberdina hartzen du. Isilik Edonorra itzuli beharrean, pyright-ek Ezezaguna (oraindik zehaztu ez den mota) eta Edozein (mota egiaztatzeko aukera esplizituki ezabatu) bereizten ditu. Pyright-en modu zorrotzean x = [] idazten duzunean, zerrenda[Ezezaguna] ondorioztatzen du eta diagnostiko baten berri ematen du, ohar bat ematera behartuz.

Pyright ere oldarkorragoa da esparrua murrizteari buruz. Idazten baduzu:

  • x = [] eta ondoren x.append("kaixo") - pyright-ek zerrenda[str]
  • ondorioztatzen du
  • x = [] ondoren x.append(1) eta gero x.append("kaixo") — pyright-ek zerrenda[int | str
  • x = [] zuzenean list[int] espero duen funtzio batera pasatu da — pyright-ek list[int] dei-gunearen testuingurutik ondorioztatzen du
  • x = [] itzulera motako oharpenik gabeko funtzio batetik itzuli da — pyright-ek errore baten berri ematen du asmatzea baino

Norabide biko inferentzia honek (ondorengo erabilera eta dei-guneetatik espero diren motak erabiliz) pyright-a mypy baino zehatzagoa da ontzi hutsetarako. Konpromisoa verbositatea da: pyright-en modu zorrotzak gutxi gorabehera %30-40-a arazo gehiago markatzen ditu oharrik gabeko kode-oinarri tipiko batean mypy-ren modu zorrotzarekin alderatuta, kode irekiko migrazio-txosten batzuen analisien arabera. Backend sistema konplexuak eraikitzen dituzten taldeentzat —esan, CRM, nominak eta analisiak barne hartzen dituen interkonektatutako 207 modulu kudeatzen dituen plataforma bat— pyright-en zorroztasunak inferentzia aringarriak galduko lituzkeen interfaze-desegokitasun sotilak harrapatzen ditu.

Pytype eta Pyre: Gutxien Ibiltzen diren Errepideak

Google-ren pytype-k ikuspegi pragmatikoena hartzen du agian. Oharpenak eskatu edo Edozeinera itzuli beharrean, pytype-k programa osoko analisia erabiltzen du edukiontzi bat funtzio-mugetan zehar nola erabiltzen den jarraitzeko. Funtzio batean zerrenda huts bat sortzen baduzu eta osoak gehitzen dituen beste bati pasatzen bazaio, pytype-k askotan list[int] ondorioztatu dezake inolako oharrik gabe. Funtzio gurutzatuko inferentzia hau konputazionalki garestia da — pytype mypy edo pyright baino nabarmen motelagoa da kode-oinarri handietan — baina positibo faltsu gutxiago sortzen ditu oharrik gabeko kodean.

Pytypek "mota partzialak" kontzeptua ere aurkezten du edukiontzi hutsetarako. Sortu berri den [] mota partzial bat lortzen da, eta pixkanaka hobetzen den egiaztatzaileak erabilera gehiago aurkitzen duen heinean. Hau kontzeptuz dotorea da, baina errore-mezu nahasgarriak sor ditzake mota partziala guztiz konpondu ezin denean, esate baterako, edukiontzi huts batek hainbat funtzio igarotzen dituenean inoiz bete gabe.

💡 DID YOU KNOW?

Mewayz replaces 8+ business tools in one platform

CRM · Invoicing · HR · Projects · Booking · eCommerce · POS · Analytics. Free forever plan available.

Start Free →

Meta-ren piroa, berriz, mypyren portaeratik hurbilago dago baina lehenespen zorrotzagoekin. Pyre-k x = [] zerrenda[ezezaguna] gisa tratatzen du eta oharrak eskatzen ditu testuinguru gehienetan. Pyre-k bere burua bereizten duen kvarg gisa erabiltzen diren hiztegi hutsakren erabileran da — web esparruetan ohikoa den eredua. Pyre-k kasu bereziko logika du hiztegi-motak gako-argumentu-testuinguruetatik ondorioztatzeko, marko-astuneko kode-oinarrietan oharpen-zama murriztuz. Web-aplikazio moderno gehienek hiztegia desegitearen erabilera handia dakartela konfiguraziorako eta eskaerak kudeatzeko, pragmatismo honek fruituak ematen ditu.

Mundu errealeko eragina: inferentzia dibergentzia hozka egiten denean

Mota-zuzentzaileen arteko desberdintasunak akademikoak dirudite produkzio-kode-base batean bizi arte. Demagun negozio-aplikazioetan ohiko eredu bat: baldintzapean betetzen den datu-egitura bat hasieratzea.

Ontzi hutsik arriskutsuenak ez dira mota-zuzentzaileak markatutakoak; ondorioztaturiko Edozein mota batekin isilean pasatzen direnak dira, datu bateraezinak abisurik gabe pilatzea ahalbidetzen baitute beherako funtzio bat exekuzioan huts egiten duen arte, jatorrian ia ezinezkoa den TypeError batekin.

Adibide konkretu bat: fintech startup bateko talde batek hiru egun eman zituela ekoizpen-arazo bat arazketa non zerrenda huts bat, ordainketak prozesatzeko funtzio batean hasieratuta, mypy-k zerrenda[Edozein] gisa ondorioztatu zuen. Zerrendak Dezimal objektuak izan behar zituen moneta-kopuruetarako, baina kode-bide batek float balioak gehitzen ari ziren. Mypyren inferentzia arinek isilean baimendu zuen. Akatsa float aritmetikan biribiltzeak 0,01 $-ko desadostasuna eragin zuenean bakarrik agertu zen 12.000 fakturako lote batean. Pyright modu zorrotzean erabili izan balute, edo hutsik dagoen zerrenda zerrenda[Decimal] gisa idatzita, akatsa garapen garaian harrapatuko zatekeen.

Mewayz-en, non plataformak fakturazioa, nomina-kalkuluak eta finantza-analisiak prozesatzen ditu 138.000 erabiltzaile-kontu baino gehiagotan, mota-segurtasun-hutsune hori ez da teorikoa; nomina zuzenaren eta birkalkulatze garestien arteko aldea da. Edukiontzien hasieraren inguruan idazteko diziplina zorrotza ekoizpen-intzidentzia zirraragarriak saihesten dituen ingeniaritza-praktika "aspergarri" horietako bat da.

Defentsarako edukiontzien hasierarako praktika onak

Zure taldeak erabiltzen duen egiaztatzaile mota edozein dela ere, estrategia zehatzak daude edukiontzi hutsaren anbiguotasuna guztiz kentzeko. Helburua da edukiontzi hutsetarako inferentzian ez fidatzea. Mota esplizitu egin ezazu zure kodea egiaztatzaile guztietan eramangarria izan dadin eta bertsioen arteko inferentzia-portaera aldaketekiko immunea izan dadin.

  1. Apuntatu beti edukiontzi hutsen aldagaiak. Idatzi emaitzak: list[int] = [] emaitzak = []ren ordez. Adierazpen txikiaren kostua arbuiagarria da aurreztutako arazketa denborarekin alderatuta. Praktika bakar honek edukiontzi hutsen inferentzia arazoen % 80 gutxi gorabehera ezabatzen du.
  2. Erabili fabrikako funtzioak edukiontzi konplexuetarako. cache = {}-en ordez, idatzi def make_cache() -> dict[str, list[UserRecord]]: return {} bezalako funtzio bat. Itzultzeko motako oharpenak nahi den mota anbiguoa eta berez dokumentatzen du.
  3. Nahiago idatzitako eraikitzaileak mota ez-trivialetarako literalak baino. Idatzi elementuak: set[int] = set() multzoko ulermenaren inferentzian oinarritu beharrean. defaultdict eta Kontagailuarako, eman beti mota-parametroa: counts: Counter[str] = Counter().
  4. Konfiguratu zure mota egiaztatzailearen modu zorrotza kode berrirako. Mypy eta pyright-ek fitxategi bakoitzeko edo direktorio bakoitzeko konfigurazioa onartzen dute. Gaitu modulu berrien egiaztapen zorrotza, pixkanaka-pixkanaka ondarea kodea migratzen duzun bitartean. Horrek inplizituki idatzitako edukiontzi berriak pilatzea eragozten du.
  5. Gehitu mota-zuzentzaileen konparaketa zure CI kanalizazioan. Mypy eta pyright zure kode-oinarrian exekutatzen badituzu, inferentzia-dibergentzia hasieran ikusten da. Eredu batek egiaztatzaile bat gainditzen badu baina beste batek huts egiten badu, mota nahikoa esplizitua ez den seinale da.

Irudi handiagoa: mota egiaztatzea taldeko praktika gisa

Edukiontzi hutsaren inferentzia, azken finean, Python-en sistema motako erronka handiago baten mikrokosmosa da: erosotasunaren eta segurtasunaren arteko tentsioa. Python-en "guztiok adostasun helduak gara" filosofiak ederki funtzionatzen du prototipoak eta gidoiak egiteko, baina milaka erabiltzaileri zerbitzatzen dituzten ekoizpen sistemek berme sendoagoak behar dituzte. Lau mota-zuzentzaile nagusiek [] mota bezain oinarrizko zerbaitetan ados ez egoteak azpimarratzen du Python idazketa-ekosistema oraindik heltzen ari dela.

Plataforma konplexuak eraikitzen dituzten ingeniaritza taldeentzat - mikrozerbitzu gutxi batzuk edo Mewayz-en negozioko sistema eragilea bezalako ehunka modulurekin batera konektatuta dauden sistema integratua kudeatzen ari zaren ala ez, aholku praktikoa erraza da: ez izan ontzi hutsetarako inferentzian oinarritu, hautatu mota-zuzentzaile bat eta konfiguratu zorrozki, eta tratatu mota-oharpenak gerta daitezkeen dokumentazio gisa. []ren ordez [] zerrenda[Faktura] idazten emandako bost minutuek arazketa-orduak aurreztuko dituzte zure kode-basea eskalatzen denean.

PEP 696 (mota-parametro lehenetsiak) eta PEP 695 (mota-parametroaren sintaxia) Python-en bertsio berriagoetan jarraitzen dutenez, idazketa esplizituaren ergonomia hobetzen joango da. "Anotatutako" eta "anotatu gabeko" Python-en arteko aldea murriztuko da. Baina egun horretara arte, edukiontzi mota esplizituak Python-en garatzaileen tresna-tresnaren ROI praktiketako bat izaten jarraitzen dute; modulu guztietan, sprint guztietan eta produkzio inplementazio guztietan interes konposatua ordaintzen duen diziplina txikia da.

Eraiki zure negozioa gaur egun

Independienteetatik hasi eta agentzietaraino, Mewayz-ek 138.000 enpresa baino gehiago sustatzen ditu 207 modulu integraturekin. Hasi doan, handitzen zarenean eguneratu.

Sortu doako kontua →

Ohiko galderak

Zergatik ezin dira idatzi-zuzentzaileak ados jarri zerrenda huts baten motaren inguruan?

`x = []` idazten duzunean, mota-zuzentzaileak mota bat ondorioztatu behar du iradokizun espliziturik gabe. Zuzentzaile ezberdinek estrategia desberdinak erabiltzen dituzte: batzuek `zerrenda[Edozein]` (edozerren zerrenda) ondorioztatzen dute, beste batzuek, berriz, `zerrenda[Edozein]` bezalako mota zehatzagoa baina okerrago bat ondorioztatu dezakete. Estandar unibertsal baten falta hori horregatik ez daude ados. Zuzentzaile bat baino gehiago erabiltzen dituzten proiektuetarako, inkoherentzia hau buruhauste handia izan daiteke, beste batean gainditzen den tresna batean analisia hausten duena.

Zein da edukiontzi hutsen akatsak konpontzeko modurik errazena?

Irtenbiderik zuzenena motako oharpen esplizitua ematea da. `my_list = []`-ren ordez, idatzi `my_list: list[str] = []` nahi den mota esplizituki deklaratzeko. Horrek anbiguotasun guztiak kentzen ditu mota-zuzentzaileari, mypy, Pyright eta Pyre bezalako tresna ezberdinetan portaera koherentea bermatuz. Praktika hau edukiontzi hutsak hasieratzeko gomendatzen da inferentzia akatsak saihesteko.

Nola kudeatzen ditut edukiontzi hutsak klaseen definizioen barruan?

Hau ohiko arazoa da, klase barruko oharpenek tratamendu berezia behar dutelako. `from __future__ import annotations` inportazioa edo `ClassVar` ohartarazpena erabili behar duzu zerrenda klaseko atributu bat izan nahi bada. Adibidez, `class MyClass: my_list: ClassVar[list[str]] = []`. Hori gabe, mota-zuzentzaileak zailtasunak izan ditzake mota behar bezala ondorioztatzeko, akatsak sortuz.

Ba al dago proiektu handietan idazketa-arazo hauek kudeatzen laguntzeko tresnarik?

Bai, Pyright bezalako mota-zuzentzaile aurreratuak (Pylance aktibatzen duena VS Coden) bereziki onak dira inferentzia konplexuak kudeatzeko. Kode-oinarri handietarako, Mewayz bezalako plataformek (207 analisi-modulu eskaintzen dituzte hilean $ 19-ren truke) motaren egiaztapen sakonagoa eta koherenteagoa eskain dezakete eta zure talde osoan oharpen-praktikak ezartzen lagundu dezakete, artikuluan eztabaidatutako inkoherentziak arinduz.

Try Mewayz Free

All-in-one platform for CRM, invoicing, projects, HR & more. No credit card required.

Start managing your business smarter today

Join 30,000+ businesses. Free forever plan · No credit card required.

Ready to put this into practice?

Join 30,000+ businesses using Mewayz. Free forever plan — no credit card required.

Start Free Trial →

Ready to take action?

Start your free Mewayz trial today

All-in-one business platform. No credit card required.

Start Free →

14-day free trial · No credit card · Cancel anytime