{"id":38649,"date":"2019-10-31T22:25:04","date_gmt":"2019-10-31T19:25:04","guid":{"rendered":"https:\/\/prohoster.info\/blog\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3\/"},"modified":"2019-10-31T22:25:04","modified_gmt":"2019-10-31T19:25:04","slug":"put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","status":"publish","type":"post","link":"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","title":{"rendered":"Ce\u013c\u0161 uz 4 miljonu rindi\u0146u Python koda tipu p\u0101rbaudi. 3. da\u013ca","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Iepriek\u0161 j\u016bs iepaz\u012bstin\u0101j\u0101m ar tre\u0161o da\u013cu par to, k\u0101 uz\u0146\u0113mums Dropbox ieviesa Python koda tipu p\u0101rbaudes sist\u0113mu.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468237\/\"><img decoding=\"async\" alt=\"Ce\u013c\u0161 uz 4 miljonu rindi\u0146u Python koda tipu p\u0101rbaudi. 3. da\u013ca\" src=\"\/wp-content\/uploads\/2019\/10\/757669265e870de604388c66adef814d.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>\u2192 Iepriek\u0161\u0113j\u0101s da\u013cas: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468233\/\">pirm\u0101<\/a><\/noindex> un <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468235\/\">otra<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>\u010cetri miljoni tip\u0113t\u0101 koda rindi\u0146u<\/h2>\n<p>\nV\u0113l viena b\u016btiska probl\u0113ma (kas bija otr\u0101 popul\u0101r\u0101k\u0101 probl\u0113ma, ko uzdeva iek\u0161\u0113jie aptauju dal\u012bbnieki) bija palielin\u0101t Dropbox kodu apjomu, kas segts ar tipu p\u0101rbaud\u0113m. M\u0113s izm\u0113\u0123in\u0101j\u0101m vair\u0101kus pieejas \u0161\u012bs probl\u0113mas risin\u0101\u0161anai \u2014 no dab\u012bga tip\u0113t\u0101 koda b\u0101zes pieauguma l\u012bdz mypy komandas centieniem koncentr\u0113ties uz statisko un dinamisko tipa autom\u0101tisko izsvie\u0161anu. Rezult\u0101t\u0101 rad\u0101s iespaids, ka nav vienk\u0101r\u0161as uzvar\u0113t\u0101jas strat\u0113\u0123ijas, ta\u010du m\u0113s sp\u0113j\u0101m \u0101tri palielin\u0101t anot\u0113ta koda apjomu, apvienojot daudzus pieg\u0101jienus.<\/p>\n<p>Rezult\u0101t\u0101 m\u016bsu liel\u0101kaj\u0101 Python repozitorij\u0101 (ar backend kodu) anot\u0113t\u0101 koda rindi\u0146u skaits sasniedza gandr\u012bz 4 miljonus. Darbs pie koda statisk\u0101s tipiz\u0101cijas tika paveikts aptuveni tr\u012bs gadu laik\u0101. Mypy tagad atbalsta da\u017e\u0101dus kodu seg\u0161anas tipo zi\u0146ojumus, kas atvieglo tipiz\u0101cijas uzraudz\u012bbu. \u012apa\u0161i m\u0113s varam veidot zi\u0146ojumus par kodu ar nenoteikt\u012bb\u0101m tipos, piem\u0113ram, par skaidru tipa izmanto\u0161anu <code>Any<\/code> anot\u0101cij\u0101s, kuras nav iesp\u0113jams p\u0101rbaud\u012bt, vai par tre\u0161o pu\u0161u bibliot\u0113ku importu, kur\u0101m nav tipu anot\u0101ciju. Projekta ietvaros, lai uzlabotu tipu p\u0101rbaudes precizit\u0101ti Dropbox, m\u0113s ieguld\u012bj\u0101m, lai uzlabotu tipu defin\u012bcijas (saukta par stub failiem) da\u017e\u0101d\u0101m popul\u0101r\u0101m atv\u0113rt\u0101 koda bibliot\u0113k\u0101m centraliz\u0113taj\u0101 Python repozitorij\u0101 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/python\/typeshed\">typeshed<\/a><\/noindex>.<\/p>\n<p>M\u0113s \u012bstenoj\u0101m (un standartiz\u0113j\u0101m turpm\u0101kajos PEP) jaunas tipu sist\u0113mas iesp\u0113jas, kas \u013cauj izmantot prec\u012bz\u0101kus tipus da\u017e\u0101m specifisk\u0101m Python paraug\u0101m. Iev\u0113rojams piem\u0113rs tam ir <code>TypeDict<\/code>, kas nodro\u0161ina tipus JSON l\u012bdz\u012bgiem v\u0101rdn\u012bc\u0101m, kur\u0101m ir fiks\u0113ts virk\u0146u atsl\u0113gu kopums, katrai no kur\u0101m ir sava tipa v\u0113rt\u012bba. M\u0113s turpin\u0101sim papla\u0161in\u0101t tipu sist\u0113mu. Iesp\u0113jams, m\u016bsu n\u0101kamais solis b\u016bs uzlabot atbalstu Python skait\u013cu apstr\u0101des iesp\u0113j\u0101m.<\/p>\n<p><img decoding=\"async\" alt=\"Ce\u013c\u0161 uz 4 miljonu rindi\u0146u Python koda tipu p\u0101rbaudi. 3. da\u013ca\" src=\"\/wp-content\/uploads\/2019\/10\/297b9e823141d6cb0d2f19f9a78a1153.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Anot\u0113t\u0101 koda rindi\u0146u skaits: server<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Ce\u013c\u0161 uz 4 miljonu rindi\u0146u Python koda tipu p\u0101rbaudi. 3. da\u013ca\" src=\"\/wp-content\/uploads\/2019\/10\/c183a9227e51d847bfdb2b8f6153684f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Anot\u0113t\u0101 koda rindu skaits: klients<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Ce\u013c\u0161 uz 4 miljonu rindi\u0146u Python koda tipu p\u0101rbaudi. 3. da\u013ca\" src=\"\/wp-content\/uploads\/2019\/10\/0a8b936fa454a34c09a9c6a2694485c9.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Kop\u0113jais anot\u0113t\u0101 koda rindu skaits<\/i><\/p>\n<p>\u0160eit ir galveno iez\u012bmju p\u0101rskats par darb\u012bb\u0101m, ko veic\u0101m, lai palielin\u0101tu anot\u0113t\u0101 koda apjomu Dropbox:<\/p>\n<p>Anot\u0101cijas stingr\u012bba. M\u0113s pak\u0101peniski paaugstin\u0101j\u0101m pras\u012bbas attiec\u012bb\u0101 uz jaun\u0101 koda anot\u0113\u0161anu. M\u0113s s\u0101k\u0101m ar lintera ieteikumiem, kas ierosin\u0101ja pievienot anot\u0101cijas failiem, kuros jau ir da\u017eas anot\u0101cijas. Tagad m\u0113s pras\u0101m tipu anot\u0101cijas jaunajos Python failos un liel\u0101kaj\u0101 da\u013c\u0101 eso\u0161o failu.<\/p>\n<p>T\u012bpa zi\u0146ojumi. M\u0113s katru ned\u0113\u013cu s\u016bt\u0101m komand\u0101m zi\u0146ojumus par vi\u0146u koda tipa l\u012bmeni un sniedzam ieteikumus par to, kas b\u016btu j\u0101anot\u0113 vispirms.<\/p>\n<p>Mypy populariz\u0113\u0161ana. M\u0113s st\u0101st\u0101m par mypy da\u017e\u0101dos pas\u0101kumos un sazin\u0101mies ar komand\u0101m, pal\u012bdzot vi\u0146iem s\u0101kt izmantot tipu anot\u0101cijas.<\/p>\n<p>Aptaujas. M\u0113s veicam periodiskas lietot\u0101ju aptaujas, lai identific\u0113tu galven\u0101s probl\u0113mas. M\u0113s esam gatavi iet pietiekami t\u0101lu, lai risin\u0101tu \u0161\u012bs probl\u0113mas (pat veidojot jaunu valodu mypy pa\u0101trin\u0101\u0161anai!).<\/p>\n<p>Veiktsp\u0113ja. M\u0113s iev\u0113rojami uzlaboj\u0101m mypy veiktsp\u0113ju, izmantojot deamonu un mypyc. Tas tika izdar\u012bts, lai mazin\u0101tu ne\u0113rt\u012bbas, kas rodas anot\u0113\u0161anas proces\u0101, un lai b\u016btu iesp\u0113jams str\u0101d\u0101t ar lieliem koda apjomiem.<\/p>\n<p>Integr\u0101cija ar redaktoriem. M\u0113s izveidoj\u0101m r\u012bkus, lai atbalst\u012btu mypy palai\u0161anu popul\u0101ros redaktoros, ko izmanto Dropbox. Taj\u0101 ietilpst PyCharm, Vim un VS Code. Tas iev\u0113rojami atviegloja koda anot\u0113\u0161anas un t\u0101 darbsp\u0113ju p\u0101rbaudes procesu. \u0160\u0101das darb\u012bbas parasti ir rakstur\u012bgas eso\u0161a koda anot\u0113\u0161anai.<\/p>\n<p>Statisk\u0101 anal\u012bze. M\u0113s izveidoj\u0101m r\u012bku funkciju parakstu izvad\u012b\u0161anai, izmantojot statisko anal\u012bzi. \u0160is r\u012bks var darboties tikai sal\u012bdzino\u0161i vienk\u0101r\u0161\u0101s situ\u0101cij\u0101s, bet tas pal\u012bdz\u0113ja mums bez liel\u0101m gr\u016bt\u012bb\u0101m palielin\u0101t tipu p\u0101rkl\u0101jumu koda pus\u0113.<\/p>\n<p>Tre\u0161o pu\u0161u bibliot\u0113ku atbalsts. Daudzos m\u016bsu projektos tiek izmantots SQLAlchemy r\u012bku komplekts. Taj\u0101 tiek izmantotas Python dinamisk\u0101s iesp\u0113jas, kuras PEP 484 tipi nesp\u0113j tie\u0161i model\u0113t. M\u0113s, saska\u0146\u0101 ar PEP 561, izveidoj\u0101m atbilsto\u0161u stub failu un uzrakst\u012bj\u0101m mypy spraudni (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dropbox\/sqlalchemy-stubs\">open source<\/a><\/noindex>), uzlabojot SQLAlchemy atbalstu.<\/p>\n<h2>Gr\u016bt\u012bbas, ar kur\u0101m sask\u0101r\u0101mies<\/h2>\n<p>\nCe\u013c\u0161 uz 4 miljoniem tipiz\u0113ta koda rindi\u0146u nebija vienm\u0113r viegls. \u0160aj\u0101 proces\u0101 sask\u0101r\u0101mies ar daudz\u0101m gr\u016bt\u012bb\u0101m un izdar\u012bj\u0101m vair\u0101kas k\u013c\u016bdas. L\u016bk, da\u017eas no probl\u0113m\u0101m, ar kur\u0101m m\u0113s sastap\u0101mies. Ceram, ka st\u0101sts par t\u0101m pal\u012bdz\u0113s citiem izvair\u012bties no l\u012bdz\u012bg\u0101m situ\u0101cij\u0101m.<\/p>\n<p>Palaistie faili. M\u0113s uzs\u0101k\u0101m darbu ar nelielu failu skaita p\u0101rbaudi. Viss, kas neietilpa \u0161ajos failos, netika p\u0101rbaud\u012bts. Faili p\u0101rbaudei tika pievienoti tikai tad, kad tajos par\u0101d\u012bj\u0101s pirmie koment\u0101ri. Ja kaut kas tika import\u0113ts no modu\u013ca, kas atrad\u0101s \u0101rpus p\u0101rbaudes jomas, tas attiec\u0101s uz v\u0113rt\u012bbu veidiem <code>Any<\/code>, kuri visp\u0101r netika p\u0101rbaud\u012bti. Tas noveda pie b\u016btiskas tipiz\u0113\u0161anas precizit\u0101tes zuduma, \u012bpa\u0161i - p\u0101rejas s\u0101kumposm\u0101. \u0160\u0101ds pieg\u0101jiens joproj\u0101m p\u0101rsteidzo\u0161i labi darboj\u0101s, lai gan tipiska situ\u0101cija bija, kad failu pievieno\u0161ana p\u0101rbaudes jomai izc\u0113la probl\u0113mas cit\u0101s kod\u0113\u0161anas b\u0101zes da\u013c\u0101s. Slikt\u0101kaj\u0101 gad\u012bjum\u0101, kad tika apvienotas divas izol\u0113tas koda jomas, kur\u0101s neatkar\u012bgi bija p\u0101rbaud\u012bti tipi, izr\u0101d\u012bj\u0101s, ka \u0161o jomu tipi nav savietojami. Tas pras\u012bja veikt daudzus groz\u012bjumus anot\u0101cij\u0101s. Tagad, atskatoties, m\u0113s saprotam, ka b\u016btu bijis j\u0101izdara vismaz\u0101k\u0101 izv\u0113le un j\u0101pievieno mypy veidu p\u0101rbaudei pamata bibliot\u0113ku modu\u013ci. Tas padar\u012btu m\u016bsu darbu daudz prognoz\u0113jam\u0101ku.<\/p>\n<p>Vec\u0101 koda anot\u0101cija. Kad m\u0113s s\u0101k\u0101m str\u0101d\u0101t, mums bija apm\u0113ram 4 miljoni rindu jau eso\u0161a Python koda. Bija skaidrs, ka visu \u0161o kodu anot\u0113t \u2014 nav viegla uzdevums. M\u0113s izstr\u0101d\u0101j\u0101m r\u012bku, ko nosauc\u0101m par PyAnnotate, kur\u0161 sp\u0113j v\u0101kt inform\u0101ciju par tipiem, veicot testu laik\u0101, un pievienot tipa anot\u0101cijas kodam, pamatojoties uz v\u0101ktaj\u0101m zi\u0146\u0101m. Tom\u0113r m\u0113s nenov\u0113roj\u0101m pla\u0161u \u0161\u012b r\u012bka ievie\u0161anu. Inform\u0101cijas v\u0101k\u0161ana par tipiem bija l\u0113na, autom\u0101tiski \u0123ener\u0113t\u0101s anot\u0101cijas bie\u017ei pras\u012bja daudz roku labojumu. M\u0113s dom\u0101j\u0101m par autom\u0101tiskas \u0161\u0101 r\u012bka palai\u0161anu katras koda p\u0101rbaudes laik\u0101 vai par inform\u0101cijas v\u0101k\u0161anu par tipiem, pamatojoties uz anal\u012bzi no neliela re\u0101lu t\u012bkla piepras\u012bjumu apjoma, bet izl\u0113m\u0101m to nedar\u012bt, jo k\u0101ds no \u0161iem pieg\u0101jieniem bija p\u0101r\u0101k riskants.<\/p>\n<p>Galu gal\u0101 var atz\u012bm\u0113t, ka liel\u0101k\u0101 da\u013ca koda tika manu\u0101li anot\u0113ta t\u0101s \u012bpa\u0161nieku. M\u0113s, lai virz\u012btu \u0161o procesu pareizaj\u0101 virzien\u0101, gatavojam zi\u0146ojumus par \u012bpa\u0161i svar\u012bgajiem modu\u013ciem un funkcij\u0101m, kas j\u0101anot\u0113. Piem\u0113ram, ir svar\u012bgi nodro\u0161in\u0101t tipa anot\u0101cijas bibliot\u0113ku modulim, kas tiek izmantots simtiem vietu. Savuk\u0101rt veco pakalpojumu, kuru nomaina jauns, vairs nav tik svar\u012bgi anot\u0113t. M\u0113s ar\u012b eksperimenti\u0113jam ar statisk\u0101 anal\u012bzes izmanto\u0161anu, lai \u0123ener\u0113tu tipa anot\u0101cijas vecajam kodam.<\/p>\n<p>Cikliskie importi. Iepriek\u0161 es run\u0101ju par cikliskajiem importiem (par \u00abatkar\u012bbu klubiem\u00bb), kuru esam\u012bba apgr\u016btin\u0101ja mypy pa\u0101trin\u0101\u0161anu. Mums bija j\u0101veic nopietns darbs, lai nodro\u0161in\u0101tu mypy atbalstu vis\u0101m idiom\u0101m, kas rodas \u0161o ciklisko importu d\u0113\u013c. Nesen m\u0113s pabeidz\u0101m lielu sist\u0113mas p\u0101rdizaina projektu, kas nov\u0113rsa liel\u0101ko da\u013cu mypy probl\u0113mu saist\u012bb\u0101 ar cikliskajiem importiem. \u0160\u012bs probl\u0113mas, paties\u012bb\u0101, rad\u0101s jau projekts s\u0101kuma posmos, v\u0113l no Alore, m\u0101c\u012bbu valodas, uz kuru s\u0101kotn\u0113ji tika orient\u0113ts mypy projekts. Alore sintakse \u013cauj viegli risin\u0101t ciklisko importa komandu probl\u0113mas. M\u016bsdienu mypy ir mantojis da\u017eus ierobe\u017eojumus no savas agr\u012bn\u0101s, vienk\u0101r\u0161\u0101s realiz\u0101cijas (kas bija lieliski piem\u0113rota Alore). Python apgr\u016btina darbu ar cikliskajiem importiem galvenok\u0101rt neskaidr\u012bbas d\u0113\u013c izteikumos. Piem\u0113ram, v\u0113rt\u012bbas pie\u0161\u0137ir\u0161anas oper\u0101cijas laik\u0101 var faktisk\u0101 tikt noteikts tipu psevdon\u012bms. Mypy ne vienm\u0113r sp\u0113j identific\u0113t \u0161\u0101das lietas, l\u012bdz liel\u0101k\u0101 da\u013ca importa cikla nav apstr\u0101d\u0101ta. Alore \u0161\u0101du neskaidr\u012bbu nebija. Agr\u012bnos att\u012bst\u012bbas posmos pie\u0146emtie neizdodas risin\u0101jumi var programm\u0113t\u0101jam sag\u0101d\u0101t nepat\u012bkamu p\u0101rsteigumu p\u0113c daudz\u0101m gadiem.<\/p>\n<h2>Secin\u0101jumi: ce\u013c\u0161 uz 5 miljoniem koda rindi\u0146u un jauniem apv\u0101r\u0161\u0146iem<\/h2>\n<p>\nMypy projekts ir g\u0101jis garu ce\u013cu \u2014 no agr\u012bniem prototipiem l\u012bdz sist\u0113mai, kas kontrol\u0113 ra\u017eo\u0161anas koda tipus apjom\u0101 4 miljoni rindi\u0146u. Mypy att\u012bst\u012bbas gait\u0101 tika standartiz\u0113tas tipu nor\u0101d\u012bjumi Python valod\u0101. M\u016bsdien\u0101s apk\u0101rt Python koda tipu nor\u0101d\u012bjumiem ir izveidojusies sp\u0113c\u012bga ekosist\u0113ma. Taj\u0101 ir vieta bibliot\u0113ku atbalstam, pieejami ir r\u012bki IDE un redaktoriem, un taj\u0101 ir vair\u0101kas tipu kontroles sist\u0113mas, katrai no kur\u0101m ir savi plusi un m\u012bnusi.<\/p>\n<p>Neskatoties uz to, ka tipu p\u0101rbaude Dropbox jau tiek uztverta k\u0101 kaut kas pa\u0161saprotams, es esmu p\u0101rliecin\u0101ts, ka m\u0113s v\u0113l joproj\u0101m dz\u012bvojam Python koda tipu ziedu laikmet\u0101. Es dom\u0101ju, ka tipu p\u0101rbaudes tehnolo\u0123ijas turpin\u0101s att\u012bst\u012bties un uzlaboties.<\/p>\n<p>Ja, ja v\u0113l neesat izmantoju\u0161i tipu p\u0101rbaudi sav\u0101 pla\u0161a m\u0113roga Python projekt\u0101, tad ziniet, ka tagad ir \u013coti piem\u0113rots laiks s\u0101kt p\u0101reju uz statisko tipiz\u0101ciju. Esmu run\u0101jis ar tiem, kas veiku\u0161i \u0161\u0101du p\u0101reju. Neviens no vi\u0146iem to neno\u017e\u0113loja. Tipu kontrole padara Python par valodu, kas daudz lab\u0101k atbilst lielu projektu izstr\u0101dei nek\u0101 \"parastais Python\".<\/p>\n<p><b>Cien\u012bjamie las\u012bt\u0101ji!<\/b> Vai j\u016bs izmantojat tipu kontroli savos Python projektos?<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/vps_start\/\"><img decoding=\"async\" alt=\"Ce\u013c\u0161 uz 4 miljonu rindi\u0146u Python koda tipu p\u0101rbaudi. 3. da\u013ca\" src=\"\/wp-content\/uploads\/2019\/10\/bf2bc557ce4481dd87398515bff60e3f.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/ruvds.com\/ru-rub\/#order\"><img decoding=\"async\" alt=\"Ce\u013c\u0161 uz 4 miljonu rindi\u0146u Python koda tipu p\u0101rbaudi. 3. da\u013ca\" src=\"\/wp-content\/uploads\/2019\/10\/098d481c25b3afaba9534c686e8f943a.png\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<br \/>Avots: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ruvds\/blog\/468237\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430. \u2192 \u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0447\u0430\u0441\u0442\u0438: \u043f\u0435\u0440\u0432\u0430\u044f \u0438 \u0432\u0442\u043e\u0440\u0430\u044f \u0414\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0435 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0415\u0449\u0451 \u043e\u0434\u043d\u043e\u0439 \u0432\u0430\u0436\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 (\u044d\u0442\u043e \u0431\u044b\u043b \u0432\u0442\u043e\u0440\u0430\u044f \u043f\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u0432\u043e\u043b\u043d\u043e\u0432\u0430\u0432\u0448\u0430\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0443\u0447\u0430\u0441\u0442\u0432\u043e\u0432\u0430\u043b \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043e\u043f\u0440\u043e\u0441\u0430\u0445) \u0431\u044b\u043b\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0451\u043c\u0430 \u043a\u043e\u0434\u0430 \u0432 Dropbox, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28992,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-38649","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"lv_LV\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0443\u0442\u044c \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0442\u0438\u043f\u043e\u0432 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430. \u0427\u0430\u0441\u0442\u044c 3 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:25:04+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:25:04+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Ce\u013c\u0161 uz 4 miljonu rindu Python koda tipu p\u0101rbaudi. 3. da\u013ca | ProHoster","description":"Iepriek\u0161 j\u016bs iepaz\u012bstin\u0101j\u0101m ar tre\u0161o da\u013cu par to, k\u0101 uz\u0146\u0113mums Dropbox ieviesa Python koda tipu p\u0101rbaudes sist\u0113mu.","canonical_url":"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"lv_LV","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0443\u0442\u044c \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0442\u0438\u043f\u043e\u0432 4 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u0440\u043e\u043a Python-\u043a\u043e\u0434\u0430. \u0427\u0430\u0441\u0442\u044c 3 | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0442\u0440\u0435\u0442\u044c\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043e \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f Dropbox, \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u0443 \u0441\u0435\u0431\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u0438\u043f\u043e\u0432 Python-\u043a\u043e\u0434\u0430.","og:url":"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/put-k-proverke-tipov-4-millionov-strok-python-koda-chast-3","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:25:04+00:00","article:modified_time":"2019-10-31T19:25:04+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"38649","title":null,"description":null,"keywords":null,"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 22:54:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:05:23","updated":"2026-08-11 12:50:30","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/posts\/38649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/comments?post=38649"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/posts\/38649\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/media\/28992"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/media?parent=38649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/categories?post=38649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/tags?post=38649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}