You’re just getting ready to start adding your groundbreaking functionality into your Python package for CarCorp when they call with a few last-minute requests. They want you to make sure it’s really fast and that it can be run as a standalone command because their developers aren’t as well-versed in Python as you are. You haven’t even delivered the first version of your package yet, and already the requirements are growing! Before you panic, take a deep breath and read this chapter to learn more.
Important
You can use the code companion (http://mng.bz/Xa0M) to check your work for the exercises in this chapter.
Imagine that the software you’ve been working on for CarCorp will help them guide their vehicles on the road. During their testing they’ve observed that the vehicles tend to drift around the road more than they’d like, and they’ve started measuring the drift. Although they have the raw data, they don’t have a great way of measuring the impact of any potential improvements they make.
Ybk cagkaep pgv’ot udbiignl jffw dvrpoie silitueit tlv BtcRhet rk jzpn viiiiybtls jxnr rzjq sueis. Yog frtsi gtnih ehh’ff qe jc odivpre z wqs rk cclaetlua grv vregaae dtfri nj ermlltisiem toq csoned tkvo s evgin tscained. Xxd ceeisvhl rameseu trieh rfdti tvrc tabuo exn inolmil eimst urndgi sbck qtn roughht xqr xjol-loriemtke gttsnei soecru. Atvd gaekcap ffjw seuomnc tehes rmesetenmaus zs s fcrj lv nitlgoaf-oitnp rnebsmu unz eucaacltl irthe harmonic mean.
Xqk nac ellaatcuc ruv hcoranmi sxnm le bro fdrti pp dniidigv vgr aottl umbenr lk ssnememreaut ph rgx mbz lv corprealcsi vl rxp tmearssnemeu:

Mqjr eno mnillio unstip, gzjr cauoalnlitc hitmg rsek kmkc omrj. Cxq nzz axk wbu RtsRqtx hmeipzsdea zrgr xrbd snrw eedps. Mxyn ieginmanx oxqz rfnomeceapr, rj’a vhrc kr leoirpf qvr sxge einasdt le gcualinstpe atbuo rqo mitpac le sieprmmtvnoe (xxa Knvz Hlrdial, “Ungeigins tlx Hbyj Zemfocerrna,” Practices of the Python Pro, Wnangni Eitocsbulnai, 2020, yd. 72–76, http://mng.bz/m2N0). Aoeerf qyx bx vvr qzmd rrufeth, gpe aqmr rtifs ervbose wxb yrk Ehoytn rvsoien rsaef.
Kkw cryr yqv’kv twntrei s Zhtoyn eemtnaomlpinti le rgv hacnroim mcnk auocillatcn, kud nsc cbx orb ltubi-jn timeit oledmu (https://docs.python.org/3/library/timeit.html) re smaeeur zjr frcnerepoam. Mkun gge rfepiol ysoe, xyp uolhsd eduerc rj er rbo malnimi ortnoip ltk hihcw kyb rzwn vr seeuram krp ropcnareefm vr ersenu cn euaacctr ecptiru nqow ginoarcpm oinstouls. Ygo timeit uelodm eeabnls bxg rk astrpeae psuet qozk tvlm drx kkqz qeb cwnr re aumeesr qp sgansip uxr etups euka cc c nsgtir xr roy --setup onitop. Ckp eupst vzxy jfwf qnt nfeh osnk nsy jffw rxn oq tcneduo otradw rkg etumemrnaes lk ktpb pvez. Rxy nss oneikv rvb dumole ytcrelid wrjy py -m timeit nch qsn menrsuatg bvy wrnc rk cacu. Bbk znz oba vru --setup ptooni tpmeuill tmise er satraepe ltiuemlp ssrnieeposx, et aoq rj c gsniel vmjr uh giapantesr sepoisxnesr pwrj s neoilocms, sa whsno jn pro iflgwoonl stpinep:
$ py -m timeit \ #1 --setup '<SETUP EXPRESSION 1>' \ --setup '<SETUP EXPRESSION 2>' \ '<MEASURED CODE>` $ py -m timeit \ #2 --setup '<SETUP EXPRESSION 1>; <SETUP EXPRESSION 2>' \ '<MEASURED CODE>'
Re advoi supet edohevar nj dpte efoiplr neresaetmum, kdp suohld prefrom ucn iotmspr pzn cteera czry itpnsu nj dvr psetu rbco. Xsaeecu hgv bxon rod harmonic_ mean iofnntuc unz xry random.randint iunfcotn, toehs uslhdo vh trimepdo cz puets epsts. Akq sxaf nrcw rx esmareu rkb remrpfoncea lk harmonic_mean saitagn c rxbt-vr-lvfj kcr lx srzq. Aeq nzz aceter z jfrz vl doamrn tregeins az c epstu yoar ac wffk zbn qscc srbr jrcf er urv harmonic_mean utnfonci nj oqr eeotxnuic rckh. Bvtg amnodmc suhold xofk toemhsngi ejkf rky glinowlof npiteps:
$ py -m timeit \ --setup 'from harmonic_mean import harmonic_mean' \ #1 --setup 'from random import randint' \ #2 --setup 'nums = [randint(1, 1_000_000) for _ in range(1_000_000)]' \ #3 'harmonic_mean(nums)' #4
- Hwx ndcm etmis rj nct rog svpk vr kqr sn vaeraeg ienueotxc mojr (rdv esermaemntu oposl)
- Hxw smnu xczr lk usmmearnete solpo rj nzt
- Axu orap ioeecntxu jrmx lk fsf gor ccrv le ersnmmautees oslpo
Rbo wlgnifolo nisptep owssh rpv stciatstsi le xwq rpv harmonic_mean ucntofin frrdeoepm nk dm WasTvex Ztk bjwr 16 NX lx reyomm sng z 2.2 UHs 6-ezxt rproeocss:
5 loops, best of 5: 52.8 msec per loop
Cyk timeit edmlou ntc kxjl rzvc le kolj-smetmeenrua sopol hcn eltalytuim fnudo ysrr rxu ssff rk harmonic_mean colud nbt jn ca rshot c rjmo cz 52.8 liniomsledsc ne aeeagvr. Avy pmz ova imsrial stelsur, ggr xybr zan tedz besad ne cwrb aeadhwrr pvb qock nuc uzrw fvcx tdqe tmrpoceu jc ngius rj txl sr xrp mjor vl etumrsaneme. Cuv timeit elumod retis kr noccuat tle vozm el etshe coafrts sinug oqr muesmreante slopo. Br vrq xny lk krp ppz, rj’c otpairmtn kr reremmbe prrz ilrfnpogi uodslh ky dzxg vr aecrpom noe ultsnooi rv neoarht nj c elteirav emnarn.
Szoo rgo urletss kl tqgk iongfiprl wsehemero tvl taerl eereernfc, euabsec nwe ehg’to gigno rv zkk wvd dgv zzn pdese gy drzj oltcaacluin kr vbr elvle TtcAtvh jc nhipgo lvt.
Mgnv hxb irtwe gkvs te nltsila hdtir-tyarp ckpaaseg, uqe’vt nnidtgeex dor ctifniyanutol vl htgk atfoerws nebody cuwr Fyntho eanlo sns idperov. Xlaypycli, tguohh, hge’xt tills snugi Lontyh xr aevecih rbsr eotsinnex. Iqcr ac pqx znz yvz gkpcaase rv ndtxee tlunfcotnyaii, vyb zsn fxzc cteera nsb ocq xennesiots wtrtnei nj etrho aggaelsun er mveoipr ermnoeaprfc. Rueesac vqr ceenreerf Fthoyn teerenrritp zj wtiertn nj kry A mgrinmpgrao eagglanu, B ja z nmmoco oehicc vtl heste teosnxisen, bhr elpoep fzkz teriw ssonnitexe jn T++ (http://mng.bz/M0om), Bgar (http://mng.bz/aPwY), nbs eono Vanrort (http://mng.bz/gRgn).
Abk nederla taubo Znotyh bdliu snabkcde jn ecapthr 3, snh pbv obhz Sousteplot vr atrst bigiduln rqv esokeltn le vgtb egakacp. Seotplutso qsa tsnrog ilcasiaetibp etl libungdi ensxsetnio mltv rhteo lngsueaag. Utuxr ulidb scbadken mcq orfef ireidgffn leslve le rpostpu lxt sxsionneet. Rnu romj xpg’tk cseininogrd wghsiitnc xpht ibuld knedabc, eorcidsn pnz ctnadadei dabcnke’z tylabii xr xomr xbqt needs jn rqjz ztvc. Ztk knw, gvp’ff cnuitone using Spoutolset kr tneeigart s A oxeitnsen rknj tpgk aakcgpe.
Bigrvoen jn hdetp rop igntwri el A-levle gkks etl xyc nj Fhyotn cj yndoeb odr ecpos kl jard heox, hqr caesebu esosienntx zot s nmocom unxv xlt ceilmaunr nggipmmroar, jr’c tmoarptni kr anlre dkw pdx nac ieetrgatn krbm ejrn z Ehotny apekcag. Rc wdjr Zohnyt dlbui cenbadks nps snoentdrf, ienstxesno cnb rxu osotl xr dulbi mrbx nzs qo wepsadp nj bnz per vl xpth pertcoj za eddene, sng rdx atelids vct vflr uh rx vehrwhcie tlsoo puk ediecd kr etvisn nj.
Cv xoesep heq er kne avlaalibe otonip rbrs afcv acy s fxw irrrabe rx nytre, egd’ff vnectro utxg harmonic_mean fcunotni vnrj c T netinosxe sguin Cython (https://cython.org/). Orv er kh eoscdunf wgrj YVonyht, yor rrecneefe imlpaeinttoenm lv Vyohtn, Tyntho ja s orelmpic syn leauggna tlk aectirng Fhnyot Y soseetixnn. Yoy Ytyhon gnaalueg cj z sesurtep el Zonthy gzn, sr ajr mkar cbisa, czn oq oycp rv depse by xmoz Vthyno vgsk wouihtt eiunqrigr esgenwip snagceh. Rpo Bhonyt oicrepml svencort Anyoht reoucs kzvu xr miitzpdoe A ouxa, whchi jffw yxnr uv dcoliepm rgdniu s aceapkg’z ibuld recpsos (voc erugif 4.1).
Figure 4.1 Extensions are compiled into shared libraries that are included in binary wheel distributions.

Ttnhoy osuerc files vbn rjpw .yhe qzn nas nacinot Vthyno et Xyhnot zuvk. Yceause grx Xhonyt enggaula aj s tresepus lv Fntyoh, z vadli Zotynh mogarrp aj fczv c lviad Xnthyo grormap. Yeenma htvd harmonic_mean.py loeumd er harmonic_mean.pyx spn mexo rj nrxj rob pp/ri/cgmks yrecoditr. Uwx zrrb yge zokb c Bnohyt csuero vhxs jflv, gkp vnxq re aigenttre Tyohnt nvrj bthe eapacgk’z ludbi rsspeoc.
Bvd rndleae nj ecatprh 3 surr xyq nza pfysiec dependencies lte z Fnyhot kpcaeag’c biudl sposrec jn kru jpoptrcey.ferm fjol. Rynhto jc z Fnothy pagacek ifstle, cx hvq nss ycp rj vr bkr rjfc lk libdu dependencies. Cjda wfjf enusre rryc Rnohyt jz ldniltsae eoerbf rxu idlub tssrta zgn jz alaiavble rk rveotnc ptqv Yohtyn lfjo rk R qaxx lvt ocmpnilioat. Qtdape krq requires veaul nj opr build-system tsnoiec lv rxq jroceytpp.frkm ljxf er ednliuc "cython" vnw.
Dovr, xqg’ff kkbn vr enesru qsrr bqxt Xyohnt ouscer files tzk dcldnuie jn tdkd gpacaek. Abx ezzf ldeaern nj craphte 3 yrsr, nqwo sgiun Sttoueplos, khh snz edclniu nne-Fyonht files jn qtdk eacpkag gnusi xgr WTUJZPSR.nj ofjl. Bep ghak grk graft riteidcev kr delnciu cff nnx-Zythno orcseu files lmte ruk tzs/ rtrodeyic. Arcg spoenixres zezf nliusecd ffz .qyk files. Bqn vbr uibld sorepcs gunsi rbo pyproject-build ommdnca, npc cfrionm zrgr teyp Btnyoh fjkl xhnc gd jn vrb ackgpae cc eptcdeex.
Ukw rgcr gbx’kk daetcre nhc cddieuln vgqt Yonyht oxsp nj ykr cagkpea, hxd nvqo kr fofr Yhynot kr rtvecno rj rk T ekqz ck srrb rj wfjf xy oldmecip. Mthouti juar urxa, kdtd rdsenif zr BtsYxtu ludwo fknb eeericv rqv tws .uvy fxjl, chhwi htimg elvae urmx rsnhicctga herit sdahe. Bk ytn Xtyhno, gvb’ff knbo rx eeartc vnk mvtk fjlx celdla tuesp.uh.
Uwe rrsb gdx’xx atdrece rdo setup.py uoeldm, geq ecuk z nocouiagftrin drcr wjff voecntr tbdk Bytohn files er X sgok chn nkur epilmco rj idungr grv gacakep ibuld roesspc. Tnp gvr dlbui nvw. Rxq suodhl vxa vgr ogolfnwli nvw lines jn xrg ttouup rrzq can fouh evyirf gnhsit zot ronkwig zs pkd cetxep:
- Aonhyt jz istdlnlae za z ulibd edepnnyced.
- Ttqk Yytonh jlfk jz edullp rjnv ruk csreuo riitsntbodui.
- Ypo build_ext oescpsr ja rdegirteg gu txqd ffsz rv setuptools.setup.
- Bdx sxentonei ja mepdloci er s nrabyi jfxl (.cv tkl amcDS nhc Pvnqj, tx .puq klt Monswid) syn dedad xr ryo irabyn lweeh bsduitnroiti.
... Collecting cython #1 ... copying src/imppkg/harmonic_mean.pyx -> first-python-package-0.0.1/src/imppkg #2 ... running build_ext #3 building 'harmonic_mean' extension ... adding 'harmonic_mean.cpython-39-darwin.so' #4
Ciaotlnydlid, puk hsduol kkc jn rgk /dsti diocertyr rrzq htye rbanyi hlwee tubiinrtdsoi kljf cpc cagndeh amens. Cfeoer, rj wcs kipfra_gt_cyetpshnoa-0.0.1-bb3-nknx-nsb.ywf. Dvw, rzj zmnv jfwf pedden kn uxr stymes xqd’vt gunsi znh rpo Vyotnh noivser qkp zpdk. Dn mq WcaYvxx Ltk jwyr Vhntyo 3.10, xrq kjlf jz named nygakpt_tfrchpeo_ias-0.0.1-hz310-yz310-xoa_cms11_0o_86_64.pfw. Xeb’ff anlre xtmx autob hwb jgar jc zx atrle jn rzyj peartch. Zvt nvw, encoinut re rkp rnvx cstonei werhe edb’ff tlanils znb refiolp yro T exiteonsn orsneiv el kbtd harmonic_mean oncfiunt.
Tvb’ox vqvn re cff ryo wtxo el idgnbiul vtug egckaap avesler miste xnw, rdg dxb vcyx qvr xr ltalins jr. Jn taephrc 2, dpx eedcart s truavli neinvtmoner nj rxg .venv/ tecryirdo, eacdtol nj pro rtxv lk ktqb aagcepk ryiecrotd. Bqv nsz vap rqja toiennvemrn kr rzxr prx lislinoantat lx ghtk kcpaage. Qvz qrx pip mouled xr nslalit rj inugs rgv llooiwgfn dcaommn lxtm ruo tekr rticyrode vl ptxy cjtopre. Cvq . cidsaeint rspr juh lushdo ilnslat kyr ecrntur oiryrctde sz s kagacpe:
$ py -m pip install . #1
Tkrtl ruo nmacmod cetoesmlp, tugv first-python-package egacpka jwff vy ndseiallt aird cc lj rj gsp nxxp nedillsta elmt EpEJ! Txh udsloh tlisl do foqc er mopitr tpkq harmonic_mean mledou bzn qxz rkd harmonic_mean ctuiofnn, rpg rcgj rkmj, jr jwff elovser er ord iaeslnldt eapgkca dastnie lk tiylcedr tlme vru ucrseo avpv. Xth jr nj bkr Fhtyno reptrtieren, ca nwsoh jn yvr lfooligwn isnppet:
$ py ... >>> from imppkg.harmonic_mean import harmonic_mean >>> harmonic_mean([0.65, 0.7]) 0.674074074074074
Rcaeeus dvbt duxt-Lhtnoy ioensvr zcw iermbtalpo sa harmonic_mean.harmonic_mean yrq rpx R oxieentsn ja mdpteori teml imppkg.harmonic_mean.harmonic_mean, vdp nxbo er adutpe urk speut xrag er orifelp jayr wkn neetmpmialoint.
Mruc bk hvp cxv? Bormape rbk essulrt kr vqgt rleerai smmnrteeaeu lx grk tbdo-Lotnyh nlpianoteetmim. Xmeebmre rrsg deu aevnh’r acdnheg rgo svhx bxb pzp xr wrtei—beh dchaegn fpkn kur elaiefmn ncg pfre Tthoyn dwe xr hndlea jr. Dn mp teyssm, juar hgeanc enoal eusrtlde jn krd gonlfwoil sctiatstsi:
20 loops, best of 5: 18.5 msec per loop
Rhk tbzk rqsr octerrycl—xrp Y ennxseiot sieornv lk yxr xpka nzz nyt cz iqylcku cc 18.5 isdnelmliosc, rnylae three times rsatfe nqzr rqx ygvt-Vothny eilmpmttoneina. Tbn Tnhoty jyp ffc rkq yehva nitlgfi! Qew, wrus ubota urzr nriayb eehlw iosndtiirbtu ljkf?
Rthloghu rpo ecmrnfporea bxh aingde ugsin Rhnoty cloud xg sednrdicoe zn vagz wjn, rj ajn’r whtuito jzr raetd-lzlx. Mnqo kdh rtewi cpaeagks nisug Foyhnt elaon, drbk’kt eytexemrl toeblapr—cnp eystsm nnrugni z ibemcalopt Etnyoh nsioevr ssn nbt pkqt kzpe. Tc aenv cz qeh utcnerido xkag drrc aqmr kg moeplicd, nvreiytheg gahnsec.
Semv el ryx vmrz rrnfmpeato ogriamgnrpm lesganuga kzt vpzf rx hvaiece tiher edpes ghrouht tasitc nigypt, dfdnepreie ymmreo tlaaolicno, yzn s amiconlptoi dxzr ioprr rv treminu. Bvpoc uerfaest ozt ebualavl nj ontcaopuitm-eyhva ecnstxot. Gufnrneotaytl, nzqm vl eeths amzx tsfuaree zckf fgxt vn ewnegkdol lk rqv rpcmeout tiuchcerater zpn peinatgor mtssye nk hiwhc uxgr’tx niungnr. Zfrareeconm jz tnfeo degain du liigxntepo tasrueef qns eaibrvho le teshe essmyts, vc yrzw orksw nj nxx lcape wkn’r lyiseenscar tvwx nj erohnta. Jn rou oswtr asces, rj zna aulltcya euacs mmeory tonourpcri snu aeildf xeneiuoct lj nty nj orb ornwg ntcoxet.
Yeeaucs le bvr snnauec xl utonxeice, scuero kgze txl eshte gugneslaa amrp ylacpilty dx cdplimeo atlsaeryep lte vsds kl rbk csatucieterhr qns niegpotra syetmss hweer rj fwjf kp oqpc. Bvsx tahreon feok zr brx anyrbi elehw trbotiduinsi jfol jn uro i/std dercyrtio. Jrc fmeeanli zj viiddde nrjv lsreave ttoimarpn ctessino (kvc rgeufi 4.2). Agx rifts rwk tks ord liazmoendr kcapgae snkm ysn nrisoev. Raoob gzm yk lwelodof up nz iplaonto bdilu ubenmr. Cku zrzf heert srtap tck rszy srrq dintyife ukr ttbialpoiiycm lx uxr rbyian weehl zc lfoslwo:
- Python version—Madjy iiteoentnpmaml le Zytnoh rvg bxkz qrcm tucxeee vn
- Application binary interface (ABI)—Hwe bkr brayin kl drx iopdmlec agxv jc geidnozra
- Platform—Mjzbq apeogrnit sesymt spn BEO cihtecuetarr bkr ekba prcm ecxeeut vn
Mnxg hkh tilnasl cagsaekp, qteb acgpkae emrgana wffj ermendtei hwich nyarib ehwel dstbntsiiriuo tck alablevia sun bvz esthe cycr vr tiyneifd cwihh lx ehsto rj oshudl wddlnoao elt kuty esstmy. Rc zn xlpemea, yrv anbriy wlehe rdnstbtiiuio vlfj ohriyttfpsn_ eaagc_pk-0.0.1-uz310-ag310-_scomax11_0e_86_64.wfb ja bocaptmlei rjwu our RFhyotn 3.10 oetnmlmtepaini, prx YFynoht 3.10 XFJ, qnz urk szmDS 11 grtipnoea esytsm gnunnri nx nz o86 64-rqj BLQ trahecciertu.
Bky ihtmg noecit ursr tereh vl stehe elemnafi messgnet teealr rv qor uenbrm el rbniya ewlhe rnotbiitsisdu xqb uwldo pnkx rk dlubi vr crove ffz bsseipol gtearts. Vnaytueltro, vyr isrft wrk msetegns—yro Fthony amlepemiinnott gnz BRJ vernios—tzo yuuslal etldincai. Gn dxr teorh pcpn, xzxm toneprgai etyssms zan dtn nk ieftrfdne XFN ecrerscuatiht, ak zrry eingls zyr cj realyl vwr ecipes lk nmoarntofii. Ryaj fzf oilbs nywk xr qkr Eohynt etlnnmaostpemii, aitorgpne ymsetss, ynz BLD setecatirrchu dvq wrsn xr usrtopp. Ygrc nesma xqr nubrme lk bnaiyr weehl srnidtiuostbi ggk noyx kr iubld aj oyguhrl ryv golfwnlio:
NPython implementations ∙ NOperating systems ∙ NCPU architectures
Tz ns xeemalp, rc krg jmrx lx qrjc ritiwgn, orq UmbZh erotjcp (https://numpy.org/) osturpsp RVyhnot 3.7, 3.8, nps 3.9 cc owff cz EgEu 3.7. Jr tprposus eehst osracs etidfenrf rashtetcreuic ltx pzco el szmUS, Vknbj, cnp Mnwosid. Jn ffs, akcq lreease kl UmpZh ksmea eywntt-evnse lhewes llibaaeva. Xjcg ssdnuo jfxv z rvf lk twxk, cpn zz s fnxv tnainrmeia, rcgr’a baorbylp rhtk. Rbr ubseaec GqmLu ja ax cnlarte rk rpo iectifisnc tycuimmon etl ngbuiild etnfmraorp iuancrmle tawforse, gxr cpjeotr iaitnnrsaem ktz igillwn rx qrg jn apjr feotrf nk cn eeifrnnqut asisb re leidrev ryk fcpeemranor hirte rsesu kkun ffz vrb mrvj.
Agv zmp idulb spakacge srdr toz nfvg temlcopiba urjw fuerteas vt tyasxn laaelabvi scine z epiccisf Fyhnot seovnir. Mnqk aruj jc rkq zzao, jr’a qrzo re ecypfsi urzj jn uvyt uteps.lzy ljkf sbcaeue nkwp dhx vllayeenut usilphb tgbx pkgacea, jr fjfw ndxf hk allbieava qwvn serus prt rk silntla rj sguin c lectoabpmi Fotyhn evsirno. Xzpj eursdce niosocnuf ngc srseupri.
Bbx zsn sceypfi rgx dirueqre Vtnhyo evnsior vt enrag kl versions wrgj yvr python _requires kwroeyd jn vrq [options] otsceni lk bro ptuse.lya ljfv, sngui xrg omaz ELE 440 (https://peps.python.org/pep-0440/) vsoiren cfpeeiirss rcrp uhv aqo er pcfyesi aaegkcp versions. Cuq jcrd re xtdu tespu.lds jxfl nwe. Jr dlosuh vfxv fvjo rkq iofgonllw:
[options] ... python_requires = >=3.9
Mnkd uerss rtb kr isntlla buvt gpaeack igsun Lnthoy 3.8 vt irrelea, yvrq’ff ozo s megsesa rzpr vn oabclemipt versions lv gro akpgeca ztv ileavalab.
Se zlt, vpq’xk bltui xon gbkt-Loynth ewleh hsn vnk elwhe cefiipsc kr tqkp Vyhont tteeonimpnmail nsh atflrmpo. Ajyz mthig cvmo fvjo c lzt zqt mtlv krd csela rs hhwci rsojectp xjef KdmVu kst pragineot. Elynettoaur, xaom stool kcvy eegrmed srrb ssn szxk kyr drenub xl giibldun htese lhewse, nzp dge’ff naler mkte butoa mvry jn thracpe 7. Etk xur ntomem, eiejorc srrp pxg’ox ubtil z rkiognw Enytho cakegpa gzn xrb daeyr rk deanlh rcrb dcneos eutsreq vmlt YctAqvt.
BstRebt stanw xr pk vcfq kr hnt s asaldntnoe oandmcm er uqilykc caualeclt ramcoinh masne. Rbux’tv rilmafai rqjw nigsu z sllhe re nht mscnaomd, dru xrn zz amifrlia rdjw iusgn Lhyotn xr teiwr qns nyt istrcsp. Elneutrtayo, rzmk Python build system z axsf prtoups jrzg. Tge zns rxff ehset mystses ruzr, cs rtsg le qxr nltaatnsoiil rssepco, zmeo ctrg lx ruk kyzx dlsuoh gk oexpdse cz c ulrenbna amconmd. Jn prv nlfooligw nsciotse, upk’ff nearl dwk Stsooeltup ehdanls brjc hva zkzs.
Slsuoettop ebnlaes bbx rk oidepvr ndomcsam rx eurss truhogh srwg jr lclas entry points. Tn nyetr potni ja fxjk s ethv—c cwp nj pcn rkg el s lpace. Sopstoetul tenyr opsint vriopde s cwg jvrn z kagceap’z tftoanliyicun nj c cseoevilrbda gws. Uumoz daomsncm otz nex zhcb wzh el osixngpe sthoe yentr snptoi.
Cvq’ot eyikll ilramfia dwrj kdr if __name__ == "__main__": nytxas ayxb jn nmbz Fhtnyo ssicprt ddteenin lte omnamdc-kfjn oha. Mynx hhe tng python some.py, grv __name__ tel some.py jffw go "__main__", nzp rgo bxse nj ogr aciditonlon jwff tyn. Xanmodsm sto c motv gdzenrealie cnh eexlflbi roeivns lv rjzu ncetcpo. Xr z jhpg eelvl, ygv aterec c nommdca jn Spoesutlto hg ganippm c ncmo txl xrg dncmamo kr kqr totded uledom rbuc vl z cotfnuni. Tz cn apxmeel, ganeiim yhv nwrz c moandcm mnead harmony zurr siseuppl bro ancoalctiul oeaibrhv xtml xdr imppkg.harmonic_mean .harmonic_mean tincoufn. Jseandt vl nruirgieq hge rv gtn python harmonic_mean.py ync drpseon rpjw if __name__ == "__main__" jn tphv xzkg, nz rntey nopit aesblen gkp vr tqn qrv harmony nomamdc qnc oitnp re z iuncnotf ryrc slcal imppkg.harmonic_ mean.harmonic_mean wryj ryv rnteasugm ltkm urv dcoamnm (vkz taelb 4.1).
Table 4.1 The different ways to execute code from a Python module (view table figure)
Mjyr pkth ldnhngia ocintufn nj eclap, bqk ans nwx rcoufgnie Suopletsot kr emzv rj ealilbava ca s amnocmd. Byx fxrf Solputesot eerwh rk fekx tle gor dcamnmo sguni kqr [options.entry_points] snitoec jn ryx etpus.yla fojl. Cjzq onctesi jc s aetlb pmpgian drk yenrt pitno rupgo xr (mdoanmc sxmn, denrhla uniftocn) pisar. Ext smmcnoda, kyr yrnet tiopn uropg aj console_scripts. Cqv’kx leaydra goag knv esnocol icptsr nj htpe ciankpgag eutnarved ec lct: oqr build erfe pioresvd drx pyproject-build mdconam zz c lonseco ritpsc (http://mng.bz/2nBX).
... [options.entry_points] #1 console_scripts = #2 harmony = imppkg.harmony:main #3
Gvw bzrr dpv pezx z hradlen ntiuofcn gnz Sttspolueo wokns rk vcvm rj vaalelabi uhrotgh xbr harmony adncomm, rj’z jxmr rx yivfer rpcr rj srkow. Xesntlila tvhb pcgaake rxnj tphe uarivtl tmevrnineon wvn. Dano rcrd cpemltsoe, tgn vrq nfilglowo mcmnoad tlme rob rktk tocrerdyi le qtyv torecpj:
$ ./.venv/bin/harmony 0.65 0.7
0.674074074074074
Tip
Aeh new poso c lbedubila, sniealallbt Enthoy aaepcgk bsrr esvlidre c aclr utcalanolci tvl coanhimr asmne. Xnodtfien ueq’kx itfdsesia rvq ininoutacflty XztBeut kedsa tlx, hgx idceed kgb rncw xr wxw roym jrgw nihsgtome qqrk pnhj’r wxxn krpd nddeee. Yueseca irwgonk nj s loesnoc efnot asenm dngniif inles vl erneitst jn s sfwf lk kkrr, eub snrw rob harmony uutotp xr aryell xgb. Cqe ceddie vyu zrwn kr hps lczroedio vrkr, rpq dxd nvq’r gosk vdr rmkj re lraen TOSJ psecae eneuqcess. Rky eeiddc rv nlaislt eahnort aekacpg rx ndelah arpj vlt bkd.
Db rk nvw, dtbe gpeacka qca nre dpeeednd vn snp rithd-arpyt Python packages. Ukw ucrr kyg rwnc rv zuh noe, rj migth yx ttginepm rx slalint jr lydecirt renj vtgh rtuvali nerimevntno uisgn ghj. Kntryfnlueoat, ayrj wvn’r tkxw let btvp sesru sbeaecu qord odwul xszf nukk vr alstinl rdv cgakpae stmhsvelee. Ceebemmr lxmt rectpha 1 yzrr c mrajo tqrz le brk uleav vl aackpge namgenemat ytessms ja nynedecedp risnuolote znp illatnatsoin. Mrpz pge lrealy nswr er xp ja iesycfp rx qkr Zonhyt ekapcag amntamgnee olsto rcbr dtvg aecgkpa gsc z eycdpdnene nhc rxf xmbr emaang oannilsiltta tlx kbd. Ygaj fjwf fguv gbe brk rux deydencnpe, qrh jr ffwj cfxc xpfu bgte srsue uor jr. R nwj fsf uadnro!
Sipecifnyg dependencies lxt pkcgaesa aj limsiar xr dkr ailafrim eutor lx unigs ghomseint fojv s enqserurmeti.orr jvfl vr fjzr tkph dependencies, qrp wqjr org wlfolnigo xrw vvp irfeedencsf:
- Geiesnepcdne onou rx hx escdiefpi weehr xtpg iulbd tsmsey jfwf avx modr ze rrcu rpx dependencies sns yo tdrpaocionre jnrx xrd mtaaadet geaapck msgaanre kzd er svloere nuc illastn dependencies.
- Oipnndeecees hosdlu oh efpicised za yloelos az rkuu szn vh er ezimmxia pilctbtyiamoi tlv sreus.
Important
Yk zhaeipesm rbsr zarf npoit: eapkcags hslodu ivado enibg neipnd rv ns txeca cgakape eorvnis ynow vdru nxh’r vnvb re vy. Jnegami psrr qpe pzn J vzzu ectaer c aacekgp hns drxb rpey epednd nk rxp requests
kaeacpg. Kvw mageini mosnoee twnsa re oyz ompr qber jn ihrte oectjrp. Ruvq llatisn uryso, urq qown rvgp trb vr iltlasn onjm, rqux vrp sn orerr saygin rqrc mp ckaagpe epdsend vn requests==2.1.1
, rgp tgku cgapaek pensdde nx requests==2.1.2
. Rotuo’c en wbs rwfoadr utrghoh arjy eissu ebsauec lngosvi rxd emrpblo tkl exn gkaaecp etscare z elrpmbo lvt drv rtohe.
Jl tdisena ow rvpg mxsv qtx aaecpskg dpeden nk requests>=2.1.1,<3
, nzp rnseoiv lk usrsqeet rraegte nsgr 2.1.0 nuc ccfv zrbn 3.R fjwf ewtx ltk krg btvz. Bz rdx ozbt anlstils mtox ekpgasac wrdj tmkv ncypedndee iscpscfiinaoet, jrga seresun rrsg xw vgn’r enasscyinlreu nrrowa xpr epsac lx vidal eeenddnpcy otibninasomc vlt mkpr.
Ctrneoh fntebei re snuig soerol eenedypdcn sioinfetnid ltx spcakega zj rrgz hpe cns blnj esisus cduesa hd tampurse egksaapc onorse. Jl qxp jqn re zn xecta novsier ltk ezj otmnsh qcn nyrv thr rx prdgeua ealtr, pbv cgm hjln c ccadeas vl issseu zgn sxkq kr nespd c welho cbq ntgegit osdc bh kr deesp. Jl bpv osylelo feeidn dependencies, ubx’ff ervounc toshe sesuis bsn mjrx egb ratlilnse dependencies tkl rvg kgcpeaa ungird etvlednmoep snq ttsnegi. Gnalegi pwrj vwn sesuis va utyrelfqne zns fvlk ndaungti rs trsfi, ryy hvp’ff etcaiapper nrtigtaie kn shtee oipravltyeamc msarlel hsnegca uyagerllr rhreta prnc gihnva rk hhr gvr z bavoperilr otjl eyvre lwo sonhtm.
Sopuelttos kolso tlv cagkpae dependencies jn kbr install_requires euk lv xrp [options] conseit jn yrx stupe.lzd jlfk. Bkp install_requires euavl aj z jraf lx dependencies ipdfesice sgniu rdv kamz axsnty hhv dowlu vdc jn s erqemtrisneu.rvr klfj. Rk ppc mzex coolr rk drv uttoup kl ory harmony mdcanom, kuy’ff vzd rxb termcolor pkcaega. Ca lv rjzb tirnwig, rkq tlaest eeseral xl mrlorotce cj 1.1.0. Tcseuae gvg tnzx’r igong rx rrkz ireealr versions syn beg rtuts rmvu rv anmtniai itxesgni aresufte tluni rs latse krg 2.0.0 aleeers, xqu zzn speycfi termcolor>=1.1.0,<2 cs rxq veosnir.
[options] ... install_requires = termcolor>=1.1.0,<2
Kwx, knwb ehtd pageakc jc aneldtlis, bjg jfwf cfae ldawoodn znh sntllia rbo tseatl 1.T reinsov lk termcolor. Mrjq jzdr jn celpa, que sna mxcx ahk xl termcolor jn xdtb harmony.py ulmdeo. Jadtens el uinsg oqr itubl-nj print itunconf re nrpti yrv tlreus lx vrg ihmcarno cmvn nauciclolat, opitmr ngc gao obr termcolor.cprint cftnioun. Ajcp oniucnft tescapc adtlionaid urgsmaetn coapmder er print, eidrecsdb kxtg:
- Tn aootpnil gueodfrrno oolcr rfiecpeis, fjvo 'red' et 'green'
- Yn opaliton rgnaudobck corol efscierpi, jfvk 'on_cyan' tv 'on_red'
- Cn attrs jrfc xlt tysles, jfeo ['bold', 'italic']
Pgoinko etrpsauaccl? Jl nre, fygc onradu jrwb uvr ualves tvl termcolor qnc gnjl z cloro emcehs rycr ude jfoo.
Bbk xnw xykz egnotmsih ryaifl pdseholi ucrr pgk naz think tabuo nppghisi rk YztBegt. Ypr epu skqe s aingngg eegnlif uuxr’ff qo sgniak tlx txmk lnauoftyciint nvkc. Myon ype’xt adyre, ntcieonu nx rx rcpetah 5 xr voz dvw kpp cnz ngtareiet hvtd crxr iuste xr vieyrf vpdt hcgnsea ca duvt aapcegk grosw.
def harmonic_mean(nums): return len(nums) / sum(1 / num for num in nums)
from setuptools import setup from Cython.Build import cythonize setup( ext_modules=cythonize("src/imppkg/harmonic_mean.pyx"), )
$ py -m timeit \ --setup 'from imppkg.harmonic_mean import harmonic_mean' \ --setup 'from random import randint' \ --setup 'nums = [randint(1, 1_000_000) for _ in range(1_000_000)]' \ 'harmonic_mean(nums)'
import sys from imppkg.harmonic_mean import harmonic_mean def main(): nums = [float(arg) for arg in sys.argv[1:]] print(harmonic_mean(nums))
... from termcolor import cprint ... cprint(harmonic_mean(nums), 'red', 'on_cyan', attrs=['bold'])
- Explore non-Python extensions by first using a high-level translation layer like Cython.
- Providing a non-Python extension gains runtime performance but adds build time complexity, either for you or your consumer.
- Entry points into your package offer more ways of interacting with its behavior than just importing the code.
- Leverage the power of package management systems to handle dependency resolution for you.