Páginas

terça-feira, 19 de fevereiro de 2013

Elpurigante en Python

fonto: pythonconquerstheuniverse.wordpress.com/2009/09/10/debugging-in-python/
Kiel programisto, unu el la unuaj aferoj kiujn vi bezonas por serioza programo disvolviĝo estas erarserĉilo.
 
Python havas erarserĉilo, kiu estas disponebla kiel modulo nomita pdb (por "Python debugger", nature!). Bedaŭrinde, plej diskutoj de pdb ne estas tre utilaj al Python newbie - la plimulto estas tre konciza kaj simple rehash la priskribo de pdb en la Python-biblioteka referenca manlibro. La diskuto, kiun mi trovis plej atingeblaj estas en la unuaj kvar paĝoj de Ĉapitro 27 de la Python 2.1 Biblio.
Do jen mia propra persona milda enkonduko al uzante pdb. Supozas ke vi ne uzas ajnan IDE - ke vi kodigas en Python per tekstoredaktilo kaj kuras vian Python-programoj de la komandlinio.

Iuj Aliaj Sencimigilaj Rimedoj

  • Por informo pri la sencela interaga debugger, vidu la sencelan dokumentadon
  • Por informo pri la Ala IDE debugger, vidu la Ala IDE dokumentado. Estas ĉapitro sur la Ala debugger, kaj alia ĉapitro sur antaŭita depuración teknikoj kiuj kovras elpurigante kodo ĵetis eksteren de Ala kaj / aŭ en alia gastiganto. Danke al Stephan Deibel de Ala por ĝisdatigi ĉi tiun informon.

Kiel komenci - pdb.set_trace()

Por komenci, mi montros al vi la tre plej simpla maniero uzi la Python erarserĉilo.
1. Ni komencu per simpla programo, epdb1.py.
 # Epdb1.py - eksperimenton kun la Python debugger, PDB
 a = "aaa"
 b = "BBB"
 c = "ccc"
 fina = a + b + c
 print fina
2. Enŝovi sekvantan deklaron je la komenco de via Python-programo. Tiu aserto importas la Python debugger modulo, pdb.
  import pdb 
3. Nun trovi lokon kie vi ŝatus paŭsi komenci, kaj enmetas la sekvan kodon:
  pdb.set_trace()
Do nun via programo aspektas kiel ĉi tio.
  # Epdb1.py - eksperimenton kun la Python debugger, pdb
 import pdb
 a = "aaa"
 pdb.set_trace()
 b = "BBB"
 c = "ccc"
 fina = a + b + c
 print fina
4. Nun kuri vian programon de la komanda linio kiel vi kutime faras, kiu probable aspektas tiel:
prompt> python epdb1.py 
Kiam via programo renkontas la linion kun pdb.set_trace() ĝi komencos paŭsi. Tio estas, ĝi (1) halti, (2) montri la "aktualan deklaron" (tio estas, la linio kiu ekzekuti proksima) kaj (3) atendi vian enigon. Vi vidos la pdb prompto, kiu aspektas jene:
  (pdb)

Ekzekuti la sekvantan deklaron ... kun "n" (next, proksima)

Je la (pdb) instigas, premu la minusklan literon "n" (por "proksima") en via klavaro, kaj tiam premu la [ENTER] klavo. Ĉi rakontos pdb ekzekuti la nunan deklaron. Konservu fari ĉi - premante "n", tiam [ENTER].
Eventuale vi venos al la fino de via programo, kaj ĝi finiĝas kaj redonas vin al la normala komanda prompto.
Gratulojn! Vi ĵus faris vian unuan depuración kuri!

Ripetante la lastan depuración komando ... kun ENTER

Ĉi-foje, faru la samon kiel vi faris antaŭe. Komenci vian programon kurante. Je la (pdb) instigas, premu la minusklan literon "n" (por "proksima") en via klavaro, kaj tiam premu la [ENTER].
Sed ĉi tiun fojon, post la unua fojo ke vi premas "n" kaj tiam ENTER, ne fari tion plu. Anstataŭe, kiam vi vidas la (pdb) prompto, simple premu ENTER. Vi rimarkos ke pdb daŭrigas, kvazaŭ vi estus premita "n". Do ĉi tiu estas Handy Tip #1:
Se vi premas ENTER sen eniri ion, pdb estos re-ekzekuti la lastan komandon kiu vi ĝin donis.
En ĉi tiu kazo, la komando estis "n", do vi povus simple observu tretante per la programo premante ENTER.
Rimarku ke vi pasis la lastan linion (la linio kun la "print" aserto), estis ekzekutitaj kaj vi vidis la eliron de la impresan deklaron ("aaabbbccc") montras sur via ekrano.

Lasi ĉion ... kun "q" (Quit, eliri)

La erarserĉilo povas fari ĉiajn aferojn, kelkaj el kiuj vi povas trovi tute mystifying. Do la plej grava afero por lerni nun - antaŭ vi lerni ion alian - estas kiel quit depuración!
Ĝi estas facila. Kiam vi vidas la (pdb) prompto, simple premu "q" (por "quit") kaj la [ENTER]. pdb estos quit kaj vi estos denove en via komanda prompto. Provu kaj vidu kiel ĝi funkcias.

Presi la valoron de variabloj ... kun "p" (print, premu)

La plej utila afero vi povas fari en la (pdb) prompto estas presi la valoron de variablo. Jen kiel fari ĝin.
Kiam vi vidas la (pdb) instigas, eniru "p" (por "presita") sekvata de la nomo de la variablo vi volas presi. Kaj kompreneble, vi fine premante la klavon.
Notu, ke vi povas presi multnombrajn variablojn, per disigi iliajn nomojn kun komoj (egala en regula Python "print" frazo). Ekzemple, vi povas presi la valoron de la variabloj a, b, kaj c tiamaniere:
  p a, b, c 

Kiam tio pdb montras linion?

Supozu ke vi progresis tra la programo ĝis vi vidos la linion
  fina = a + b + c
kaj vi donos pdb la komando
  p fina
Vi ricevos NameError escepto. Ĉi tio estas ĉar, kvankam vi vidas la linion, ĝi ankoraŭ ne ekzekutitaj. Do la fina variablo ankoraŭ ne estas kreita.
Nun premu "n" kaj ENTER por daŭrigi kaj ekzekuti la linion. Poste provu la "p fina" komando denove. Ĉi-foje, kiam vi donos la komando "p fina", pdb presos la valoron de fino, kiu estas "aaabbbccc".

Elŝaltante la (pdb) prompto ... kun "c" (continue, sekvi)

Vi verŝajne rimarkis, ke la "q" ordonas atingis vin el pdb en tre kruda maniero - esence, de frakasi la programon.
Se vi deziras simple ĉesi depuración, sed lasi la programon daŭrigis kuri, tiam vi volas uzi la "c" (por "daŭrigi") komandon en la (pdb) prompto. Tiu kaŭzos vian programon por daŭrigi kurante kutime, sen paŭzante por depuración. Eble kuras al finaĵo. Aŭ, se la pdb.set_trace() komunikaĵo estis interne de ciklo, eble vi renkontos ĝin denove, kaj la (pdb) depuración prompto aperos denove.

Vidante, kie vi estas ... kun "l" (list, listu)

Kiel vi elpurigas, ekzistas multe da taskoj estante skribita sur la ekrano, kaj alvenas vere malfacile akiri senton pri kie vi estas en via programo. Tie estas kie la "l" (por "list") komandon envenas (Noto ke estas minuskla "L", ne la numeralo "unu" aŭ la majusklo "I".)
"L" montras vin, sur la ekrano, la ĝenerala areo de via programo fonta kodo kiun vi ekzekuti. Implicite, ĝi listas 11 (dek unu) linioj de kodo. La linio de kodo, ke vi estas pri ekzekuti (la "aktuala linio") estas ĝuste en la mezo, kaj tie estas iom sago "->" kiu notas al tio.
Do tipa interago kun pdb iru kiel tiu
  • La pdb.set_trace() komunikaĵo estas renkontita, kaj vi komencos paŭsi kun la (pdb) prompto
  • Vi premas "n" kaj tiam [ENTER], komenci tretante per via kodo.
  • Vi nur premi [ENTER] treti denove.
  • Vi nur premi [ENTER] treti denove.
  • Vi nur premi [ENTER] treti denove. ktp ktp ktp
  • Fine, oni rimarkas, ke vi estas iom perdita. Vi ne akurate certas kie vi estas en via programo plu. Do ...
  • Vi premas "l" kaj tiam ENTER. Ĉi listas la areo de via programo kiu nuntempe estas ekzekutitaj.
  • Vi inspektas la ekrano, ricevos vian lagroj, kaj estas preta por komenci denove. Do ....
  • Vi premas "n" kaj tiam [ENTER], komenci tretante per via kodo.
  • Vi nur premi [ENTER] treti denove.
  • Vi nur premi [ENTER] treti denove. ktp ktp ktp

Tretante en subrutinoj ... kun "s" (ŝtupu en)

Fine, vi bezonos elpurigi grandajn programojn - programoj kiuj uzas subrutinoj. Kaj kelkfoje, la problemo ke vi provas trovi estos kuŝas entombigita en subrutina. Konsideru la sekvan programon.
 # epdb2.py - eksperimenton kun la Python debugger, pdb
 import pdb

 def kombinas(s1, s2): # difini subrutino kombinas, kiu ...
     s3 = s1 + s2 + s1 # sandviĉoj s2 inter kopiojn de s1, ...
     s3 = '"' + s3 + '" "# enfermas lin en duoblaj citiloj, ...
     return s3 # kaj revenas ĝi.

 a = "aaa"
 pdb.set_trace()
 b = "BBB"
 c = "ccc"
 fina = kombinas(a, b)
 print fina
Kiel vi movas tra viaj programoj uzante la 'n' ordonon ĉe la (pdb) prompto, vi trovos, ke kiam vi renkontas deklaron ke alpreĝas subrutino - la fina = kombinas(a, b) komunikaĵo, ekzemple - pdb dolĉaĵoj ĝi ne alie ol ajna alia aserto. Tio estas, la komunikaĵo estas ekzekutita kaj vi movas al la venonta frazo - en ĉi tiu kazo, presi finon.
Sed supozas ke vi suspektas ke estas problemo en subrutino. En nia kazo, supozu ke vi suspektas ke estas problemo en la kombina subrutino. Kion vi volas - kiam vi renkontos la fina = kombinas(a, b) komunikaĵo - estas iel eniri la kombinan subrutinon, kaj daŭrigi vian depuración en ĝi.
Nu, vi povas fari tion ankaŭ. Fari ĝin kun la "s" (por "paŝo al") komandon.
Kiam vi ekzekuti deklarojn kiuj ne engaĝas funkciajn alvokojn, "n" kaj "s" ĉu la samo - movi al la venonta komunikaĵo. Sed kiam vi ekzekutas deklarojn ke alpreĝas funkciojn, "s", kontraste 'n', estos paŝo al la subrutina. En nia kazo, se vi ekzekutita la
  fina = kombinas(a, b)
deklaro uzante "s", tiam la sekva aserto ke pdb montrus vi estus la unua frazo en la subrutino nomiĝita kiel kombinas():
  def kombinas(s1, s2): 
kaj vi sekvos elpurigante de tie.

Daŭrigante ... sed nur por la fino de la nuna subrutino ... kun "r" (return, reveno)

Kiam vi uzas "s" al paŝo en subrutino, vi ofte trovos vin kaptita en subrutino. Vi ekzamenis la kodon kiun vi estas interesata en, sed nun vi devas treti tra multaj seninteresaj kodoj en la subrutino.
En ĉi tiu situacio, kion vi ŝatus povi fari estas nur salti antaŭen al la fino de la subrutina. Tio estas, vi volas fari ion kiel la "c" ("sekvi") komandon faras, sed vi volas nur sekvi al la fino de la subrutina, kaj poste rekomenci vian tretante tra la kodon.
Vi povas fari ĝin. La komando por fari ĝi estas "r" (por "reveno" aŭ, pli bone, "daŭrigas ĝis reveno"). Se vi estas en subrutino kaj vi eniros la "r" komando en la (pdb) prompto, pdb daŭrigos ekzekuti ĝis la fino de la subrutino. En tiu punkto - la punkto kiam estas pretaj por reveni al la nomante rutino - ĝi haltos kaj montri la (PDB) instigas denove, kaj vi povos rekomenci tretante per via kodo.

Vi povas fari ion ajn en la (PDB) prompto ...

Kelkfoje vi estos en la sekvaj situacio - Vi kredas ke vi jam eltrovis la problemo. La deklaro kiu atribui valoron de, ni diru, "aaa" al variablo var1 estis erara, kaj kaŭzis vian programon por eksplodigi. Ĝi devus esti atribui la valoron "BBB" al var1.
... Almenaŭ, vi estas bela certa, ke estis la problemo ...
Kion vi volas vere ŝatas povi fari, nun ke vi situas la problemo, estas atribui "BBB" al var1 kaj vidu se via programo nun kuras al finaĵon sen bombado.
Ĝi povas esti farita!
Unu el la belaj aĵoj pri la (PDB) prompto estas ke vi povas fari ion ajn al ĝi - vi povas eniri iu komando ke vi ŝatas la (PDB) prompto. Do vi povas, ekzemple, eniras tiun ordonon ĉe la (PDB) prompto.
  (PDB) var1 = "BBB" 
Vi povas tiam daŭrigi al paŝo tra la programo. Aŭ vi povus esti aventura - uzo "c" elŝalti depuración kaj vidu se via programo finos sen bombardas!

... Sed estus iom singarda!

[Danke al Dick Morris por la informo en ĉi tiu sekcio.]
Ĉar vi povas fari ion ajn en la (PDB) prompto, vi eble decidos provi opcio la variablo B al nova valoro, diri "BBB", ĉi tiu maniero:
  (PDB) b = "BBB" 
Se vi faras, PDB produktas strangan erarmesaĝon pri estante nekapabla trovi objekton nomita '= "BBB"'. Kial?
Kio okazas estas ke PDB provoj por ekzekuti la PDB b komandon por opcio kaj printi breakpoints (ordono, ke ni jam ne diskutas). Interpretas la resto de la linio kiel argumento por la b komando, kaj ne povas trovi la celon, ke (kredas) estas referita al. Do ĝi produktas eraron mesaĝo.
Do kiel ni povas atribui novan valoron al b? La artifiko estas por komenci la komando kun krio punkto (!).
  (PDB)! B = "BBB" 
Ekkrion punkto diras PDB ke kio sekvas estas Python aserto, ne PDB komando.

La Fino

Nu, jen ĉio nun. Ekzistas pluraj temoj kiuj mi ne menciis, kiel helpo, alias, kaj breakpoints. Por informoj pri ili, provu la interreto referenco por PDB komandojn sur la Pitona dokumentado TTT-ejo. Krome, mi rekomendas Jeremy Jones artikolo Interactive depuración en Python en O'Reilly de Python DevCenter.
Mi esperas ke ĉi enkonduko al PDB estis sufiĉa por atingi vin kaj kurante sufiĉe rapide kaj painlessly. Bonŝancon!
-Steve Ferg

Nenhum comentário:

Postar um comentário