Hacker News

Python Tipi Yoxlayıcı Müqayisə: Boş Konteyner Nəticəsi

Şərhlər

17 min read Via pyrefly.org

Mewayz Team

Editorial Team

Hacker News

Niyə Boş Konteynerlər Python Tipi Damaları Qırır – Və Siz Bununla Nə Edə Bilərsiniz

Python-un tədricən yazma sistemi 2015-ci ildə PEP 484 tip göstərişlərini təqdim etdikdən sonra əhəmiyyətli dərəcədə yetkinləşdi. Bu gün milyonlarla tərtibatçı istehsala çatmazdan əvvəl səhvləri aşkar etmək üçün statik tipli damalara etibar edir. Ancaq bu tip sistemin hətta təcrübəli mühəndisləri də narahat edən incə, əsəbi bir küncü var: boş konteynerin hansı növü var? Annotasiya olmadan x = [] yazdığınız zaman tip yoxlayıcınız təxmin etməlidir — və müxtəlif damalar fərqli hesab edir. Bu fərqlilik böyük kod bazalarını saxlayan komandalar üçün real problemlər yaradır, burada növ damalarının dəyişdirilməsi və ya birləşdirilməsi bir gecədə yüzlərlə gözlənilməz xətaları üzə çıxara bilər.

Bu məqalə dörd əsas Python tipli dama-mypy, pyright, pytype və pyre-nin boş konteyner nəticəsinə necə baxdığını, nə üçün razı olmadıqlarını və alət seçiminizdən asılı olmayaraq tipə uyğun Python yazmaq üçün hansı praktik strategiyaları qəbul edə biləcəyinizi izah edir.

Əsas problem: Boş konteynerlər mahiyyət etibarilə qeyri-müəyyəndir

Bu zərərsiz Python xəttini nəzərdən keçirin: nəticələr = []. Nəticələr siyahı[int]dir? siyahı[str]? siyahı[dict[str, Any]]? Əlavə kontekst olmadan, həqiqətən bilmək üçün heç bir yol yoxdur. Python iş vaxtı əhəmiyyət vermir - siyahılar təbiətcə heterojendir - lakin statik tipli dama işlərini yerinə yetirmək üçün hər dəyişənə konkret tip təyin etməlidir. Bu, Python-un dinamik çevikliyi ilə statik analizin təmin etməyə çalışdığı zəmanətlər arasında əsas gərginlik yaradır.

Problem lüğətlər və dəstlər ilə birləşir. Boş {} faktiki olaraq dəst deyil, dict kimi təhlil edilir və bu, növ səviyyəli qeyri-müəyyənliyin üstünə sintaktik qeyri-müəyyənlik əlavə edir. Və iç-içə konteynerlər — defaultdict(list) və ya nəticələr = {k: [] for k in keys} hesab edin - nəticə çıxarma mühərriklərini öz hədlərinə çatdırın. Hər bir növ yoxlayıcı öz evristikası işləyib hazırlayıb və fərqlər əksər tərtibatçıların düşündüyündən daha əhəmiyyətlidir.

Real iş yüklərini emal edən istehsal sistemlərində - istər müştəri qeydlərini idarə edən CRM, istər sətir elementləri yaradan faktura modulu, istərsə də metrikləri birləşdirən analitik boru kəməri - boş konteynerlər daim başlanğıc nümunələri kimi görünür. Onların növlərinin yanlış alınması təkcə linter xəbərdarlıqları yaratmır; o, işləmə müddətinə keçən həqiqi səhvləri maskalaya bilər.

Mypy: Hər hansı örtüklə təxirə salınmış nəticə

Mypy, ən qədim və ən geniş yayılmış Python tipli yoxlayıcı, boş konteynerlərə nisbətən yumşaq yanaşır. Funksiya daxilində x = [] ilə qarşılaşdıqda, o, növ qərarını təxirə salmağa və sonrakı istifadədən element tipini çıxarmağa çalışır. x = [] və ardınca x.append(42) yazsanız, mypy list[int] nəticəsinə gələcək. Bu "qoşulmaq" strategiyası konteynerin eyni əhatə dairəsində yerləşdiyi sadə hallar üçün təəccüblü dərəcədə yaxşı işləyir.

Lakin mypy-nin davranışı kontekstdən və sərtlik parametrlərindən asılı olaraq kəskin şəkildə dəyişir. Modul əhatə dairəsində (yuxarı səviyyəli kod) və ya konteyner doldurulmazdan əvvəl başqa funksiyaya ötürüldükdə, mypy tez-tez list[Hər hansı]ya qayıdır. --strict bayrağı altında bu, xətaya səbəb olur, lakin defolt rejimdə səssizcə keçir. Bu o deməkdir ki, mypy-ni ciddi rejim olmadan işlədən komandalar tip sistemindən qaçış lyukları kimi fəaliyyət göstərən onlarla gizli tipli konteyner toplaya bilər və onun məqsədini poza bilər.

Xüsusilə incə davranış: 0.990-dan əvvəlki mypy versiyaları bəzən daxili olaraq siyahı[Naməlum] nəticə çıxarır və sonra tapşırığa görə siyahıya[Hər hansı] genişlənir. 0.990-dan sonra nəticə sərtləşdirildi, lakin dəyişiklik fərqinə varmadan icazə verən davranışa güvənən təəccüblü sayda real dünya kod bazalarını pozdu. Bu təkrarlanan mövzudur — boş konteyner nəticəsinə edilən dəyişikliklər ən pozucu tip yoxlayıcı yeniləmələri arasındadır, çünki nümunələr hər yerdə mövcuddur.

Müəllif hüququ: Ciddi Nəticə və "Naməlum" Növ

Microsoft tərəfindən hazırlanmış və VS Code-da Pylance-i gücləndirən Pyright, tamamilə fərqli bir fəlsəfi mövqe tutur. Səssizcə Hər hansıya qayıtmaq əvəzinə, müəllif hüququ Naməlum (hələ müəyyən edilməmiş növ) və Hər hansı (növ yoxlamasından açıq şəkildə imtina) arasında fərq qoyur. Müəllif hüquqlarının ciddi rejimində x = [] yazdığınız zaman o, siyahı[Naməlum] çıxarır və sizi annotasiya təqdim etməyə məcbur edən diaqnostik hesabat verir.

Pyright həmçinin əhatə dairəsini daraltma mövzusunda daha aqressivdir. Yazsanız:

  • x = [] və ardınca x.append("salam") — müəllif hüququ list[str]
  • nəticə verir
  • x = [], ardınca x.append(1), sonra x.append("salam") — müəllif hüququ nəticə çıxarır list[int | küç]
  • x = [] birbaşa list[int] gözləyən funksiyaya keçdi — pyright zəng saytının kontekstindən list[int] nəticə çıxarır
  • x = [] qaytarılma növü annotasiyası olmayan funksiyadan qaytarıldı — pyright təxmin etmək əvəzinə xəta haqqında məlumat verir

Bu iki istiqamətli nəticə (həm sonrakı istifadədən, həm də zəng saytlarından gözlənilən növlərdən istifadə etməklə) pyrightı boş konteynerlər üçün mypy ilə müqayisədə daha dəqiq edir. Mübadilə geniş məlumatdır: bir neçə açıq mənbəli miqrasiya hesabatlarının təhlilinə əsasən, pyright-ın ciddi rejimi mypy-nin ciddi rejimi ilə müqayisədə tipik qeyd olunmamış kod bazasında təxminən 30-40% daha çox problemi qeyd edir. Mürəkkəb backend sistemləri yaradan komandalar üçün - məsələn, CRM, əmək haqqı və analitikanı əhatə edən 207 bir-birinə bağlı modulu idarə edən platforma - pyright-ın ciddiliyi yumşaq nəticənin əldən verəcəyi incə interfeys uyğunsuzluqlarını tutur.

Pytype və Pyre: Az Səyahət Edilən Yollar

Google-un pytype versiyası bəlkə də ən praqmatik yanaşmadır. Annotasiya tələb etmək və ya Hər hansıya qayıtmaq əvəzinə, pytype konteynerin funksiya sərhədləri boyunca necə istifadə edildiyini izləmək üçün bütün proqram analizindən istifadə edir. Bir funksiyada boş siyahı yaratsanız və onu tam ədədlər əlavə edən digərinə ötürsəniz, pytype çox vaxt heç bir qeyd etmədən list[int] haqqında nəticə çıxara bilər. Bu çarpaz funksiyalı nəticə hesablama baxımından baha başa gəlir – pytype böyük kod bazalarında mypy və ya pyright ilə müqayisədə xeyli yavaşdır – lakin qeyd olunmamış kodda daha az yanlış müsbət nəticə verir.

💡 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 →

Pytype həmçinin boş konteynerlər üçün "qismən növlər" anlayışını təqdim edir. Təzə yaradılmış [] yoxlayıcı daha çox istifadə ilə qarşılaşdıqca tədricən təkmilləşdirilmiş qismən növ əldə edir. Bu, konseptual olaraq zərifdir, lakin qismən növ tam həll edilə bilməyəndə, məsələn, boş konteyner heç doldurulmadan bir neçə funksiyadan keçdikdə çaşdırıcı xəta mesajları yarada bilər.

Meta pyresi isə mypy-nin davranışına daha yaxındır, lakin daha sərt defoltlarla. Pyre x = []-ni siyahı[naməlum] kimi qəbul edir və əksər kontekstlərdə annotasiya tələb edir. Pirenin fərqləndiyi yer onun kvarqlar kimi istifadə edilən boş lüğət hərfləri ilə işləməsidir — veb çərçivələrdə ümumi nümunə. Pyre açar söz arqumenti kontekstlərindən lüğət növlərini çıxarmaq üçün xüsusi məntiqə malikdir, çərçivə ağır kod bazalarında annotasiya yükünü azaldır. Nəzərə alsaq ki, əksər müasir veb proqramlar konfiqurasiya və sorğuların idarə edilməsi üçün lüğətin qablaşdırılmasından çox istifadəni nəzərdə tutur, bu praqmatizm dividendlər ödəyir.

Real-Dünya Təsiri: Nəticə Divergensiyası Bitdikdə

Növ damaları arasındakı fərqlər, siz onları istehsal kod bazasında təcrübədən keçirənə qədər akademik görünə bilər. Biznes tətbiqlərində ümumi nümunəni nəzərdən keçirin: şərti olaraq doldurulan məlumat strukturunun işə salınması.

Ən təhlükəli boş konteynerlər dama işarəsi tipli olanlar deyil - onlar, mənşəyini izləmək demək olar ki, mümkün olmayan TypeError ilə işləmə zamanı aşağı axın funksiyası qəzaya uğrayana qədər uyğun olmayan məlumatların xəbərdarlıq edilmədən toplanmasına imkan verən təxmin edilən İstənilən növlə səssizcə keçənlərdir.

Konkret misal: fintech startapında bir komanda istehsal probleminin aradan qaldırılmasına üç ​​gün sərf etdiyini bildirdi, burada ödəniş emal funksiyasında işə salınmış boş siyahı mypy tərəfindən list[Hər hansı] kimi nəticələndi. Siyahıda valyuta məbləğləri üçün Ondalıq obyektlər olmalı idi, lakin kod yolu əvəzinə float dəyərləri əlavə edirdi. Mypy-nin yumşaq qənaəti buna səssizcə icazə verdi. Səhv yalnız float arifmetikasında yuvarlaqlaşdırma xətaları 12.000 faktura toplusunda 0,01 dollar uyğunsuzluğa səbəb olduqda ortaya çıxdı. Əgər onlar ciddi rejimdə pir hüququndan istifadə etsəydilər və ya sadəcə boş siyahıya siyahı[Ondalıq] kimi şərh versəydilər, səhv işlənmə zamanı aşkarlanardı.

Platformanın 138.000-dən çox istifadəçi hesabı üzrə hesab-faktura, əmək haqqı hesablamaları və maliyyə analitikasını emal etdiyi Mewayz-də bu növ təhlükəsizlik boşluğu nəzəri deyil - bu, düzgün əmək haqqı cədvəlləri ilə bahalı yenidən hesablamalar arasındakı fərqdir. Konteynerin işə salınması ilə bağlı ciddi yazma intizamı maraqlı istehsal insidentlərinin qarşısını alan "darıxdırıcı" mühəndislik təcrübələrindən biridir.

Müdafiə Konteynerinin Başlanması üçün Ən Yaxşı Təcrübələr

Komandanızın hansı növ yoxlayıcıdan istifadə etməsindən asılı olmayaraq, boş konteyner qeyri-müəyyənliyini tamamilə aradan qaldırmaq üçün konkret strategiyalar mövcuddur. Məqsəd heç vaxt boş konteynerlər üçün nəticəyə etibar etməməkdir — kodunuz bütün damalarda daşına bilən və versiyalar arasında nəticə çıxaran davranış dəyişikliklərindən qorunmaq üçün növü açıq-aşkar edin.

  1. Həmişə boş konteyner dəyişənlərinə şərh yazın. nəticələr = [] əvəzinə nəticələr: list[int] = [] yazın. Xırda təfərrüat dəyəri qənaət edilmiş sazlama vaxtı ilə müqayisədə cüzidir. Bu tək təcrübə boş konteynerdən nəticə çıxarma məsələlərinin təxminən 80%-ni aradan qaldırır.
  2. Mürəkkəb konteynerlər üçün zavod funksiyalarından istifadə edin. cache = {} əvəzinə, def make_cache() -> dict[str, list[UserRecord]] kimi funksiya yazın: qaytar {}. Qaytarma növü annotasiyası nəzərdə tutulan növü birmənalı və özünü sənədləşdirən edir.
  3. Qeyri-trivial növlər üçün literallardan çox tipli konstruktorlara üstünlük verin. Çoxluğu başa düşmə nəticəsinə etibar etməkdənsə, elementlər: set[int] = set() yazın. defaultdictCounter üçün həmişə növ parametrini təmin edin: sayırlar: Counter[str] = Counter().
  4. Yeni kod üçün növ yoxlayıcınızın ciddi rejimini konfiqurasiya edin. Həm mypy, həm də pyright hər fayl və ya hər kataloq konfiqurasiyasını dəstəkləyir. Köhnə kodu tədricən köçürərkən yeni modullarda ciddi yoxlamanı aktiv edin. Bu, gizli tipli yeni konteynerlərin yığılmasının qarşısını alır.
  5. CI boru kəmərinizə növ yoxlayıcı müqayisəsi əlavə edin. Kod bazanızda həm mypy, həm də pyright-ın işlədilməsi nəticə fərqini erkən tutur. Nümunə bir yoxlayıcıdan keçsə, digərini keçə bilmirsə, bu, növün kifayət qədər aydın olmadığına işarədir.

Daha Böyük Şəkil: Komanda Təcrübəsi kimi Tip Yoxlama

Boş konteynerdən nəticə çıxarmaq Python tipli sistemdə daha böyük problemin mikrokosmosudur: rahatlıq və təhlükəsizlik arasındakı gərginlik. Python-un "biz hamımız böyüklərə razıyıq" fəlsəfəsi prototipləmə və skriptlər üçün gözəl işləyir, lakin minlərlə istifadəçiyə xidmət edən istehsal sistemləri daha güclü zəmanətlərə ehtiyac duyur. Dörd əsas növ damanın [] növü kimi sadə bir şeylə razılaşmaması faktı Python yazma ekosisteminin hələ də yetkinləşdiyini vurğulayır.

Mürəkkəb platformalar quran mühəndis komandaları üçün – istər bir neçə mikroservis, istərsə də Mewayz-in biznes ƏS-i kimi bir-biri ilə əlaqəli yüzlərlə modulu olan inteqrasiya edilmiş sistemi idarə edirsinizsə, praktiki məsləhət sadədir: boş konteynerlər üçün nəticəyə etibar etməyin, tip yoxlayıcı seçin və onu ciddi şəkildə konfiqurasiya edin və bu cür sənədləri maşın kimi qəbul edin. [] əvəzinə siyahı[Invoice] yazmağa sərf olunan beş dəqiqə kod bazanız miqyası böyüdükdə saatlarla sazlamaya qənaət edəcək.

PEP 696 (defolt tip parametrlər) və PEP 695 (tip parametr sintaksisi) daha yeni Python versiyalarında yerləşməyə davam etdikcə, açıq şəkildə yazmağın erqonomikası təkmilləşməyə davam edəcək. "Annotasiya edilmiş" və "annotasiya edilməmiş" Python arasındakı boşluq daralacaq. Lakin o günə qədər açıq konteyner növləri Python tərtibatçısının alətlər dəstində ən yüksək ROI təcrübələrindən biri olaraq qalır – hər modul, hər sprint və hər istehsal yerləşdirməsi üzrə mürəkkəb faiz ödəyən kiçik intizam.

Bu gün Biznes ƏS-inizi Yaradın

Frilanserlərdən tutmuş agentliklərə qədər Mewayz 207 inteqrasiya modulu ilə 138.000+ biznesə səlahiyyət verir. Pulsuz başlayın, böyüdükcə təkmilləşdirin.

Pulsuz Hesab Yaradın→

Tez-tez verilən suallar

Niyə dama dama boş siyahının növü ilə razılaşa bilmir?

Siz `x = []` yazdığınız zaman tip yoxlayıcısı açıq göstərişlər olmadan bir növ çıxarmalıdır. Fərqli dama müxtəlif strategiyalardan istifadə edir: bəziləri `siyahı[Hər hansı]` (hər hansı bir şeyin siyahısı), digərləri isə `siyahı[Yox]` kimi daha konkret, lakin səhv növ nəticə çıxara bilər. Ümumbəşəri standartın olmaması onların razılaşmır. Çoxsaylı dama istifadə edən layihələr üçün bu uyğunsuzluq böyük başağrısı ola bilər.

Boş konteyner xətalarını düzəltməyin ən sadə yolu hansıdır?

Ən sadə həll yolu açıq tipli annotasiya təqdim etməkdir. Nəzərdə tutulan növü açıq şəkildə elan etmək üçün `my_list = []` əvəzinə `my_list: list[str] = []` yazın. Bu, növ yoxlayıcısı üçün bütün qeyri-müəyyənliyi aradan qaldırır, mypy, Pyright və Pyre kimi müxtəlif alətlər arasında ardıcıl davranışı təmin edir. Nəticə xətalarının qarşısını almaq üçün bu təcrübə bütün boş konteyner inisializasiyaları üçün tövsiyə olunur.

Sinif tərifləri daxilində boş konteynerləri necə idarə edə bilərəm?

Bu, ümumi problemdir, çünki siniflərdəki annotasiyalar xüsusi işlənmə tələb edir. Siyahının sinif atributu olması nəzərdə tutulursa, `from __future__ import annotations` idxalından və ya `ClassVar` annotasiyasından istifadə etməlisiniz. Məsələn, `class MyClass: my_list: ClassVar[list[str]] = []`. Bu olmadan, tip yoxlayıcı növü düzgün nəticə çıxarmaqda çətinlik çəkə bilər və bu, xətalara səbəb ola bilər.

Böyük layihələrdə bu yazma problemlərini idarə etməyə kömək edəcək alətlər varmı?

Bəli, Pyright kimi qabaqcıl tip dama (VS Kodunda Pylance-ə güc verir) mürəkkəb nəticə çıxarmaqda xüsusilə yaxşıdır. Böyük kod bazaları üçün Mewayz kimi platformalar (ayda 19 dollara 207 analiz modulu təklif edir) daha dərin, daha ardıcıl tip yoxlanışı təmin edə və məqalədə müzakirə olunan uyğunsuzluqları azaldaraq bütün komandanızda annotasiya təcrübələrini tətbiq etməyə kömək edə bilər.

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