Ĉapitro 3 - Funkcioj
Subtenu la Aŭtoro: Aĉeti la libron sur Amazono aŭ
la libro / ebook pakaĵo rekte Neniu amelo Gazetaro .
Legi la aŭtora aliaj liberaj Python libroj:
funkcioj
Vi jam konas la
print()
, input()
, kaj len()
funkcioj de la antaŭaj ĉapitroj. Python provizas plurajn builtin funkcioj kiel tiuj, sed vi povas ankaŭ skribi viajn proprajn funkciojn. Funkcio estas kiel mini-programo ene de programo.
Por bone kompreni kiel funkcias labori, ni kreos unu. Tajpu tiun programon en la dosiero redaktoro kaj konservi ĝin kiel helloFunc.py:
❶ def saluton (): ❷ print ( 'Howdy!') presi ( 'Howdy !!!') presi ( 'Saluton tie.') ❸ saluton () saluton () saluton ()
La unua linio estas
def
komunikaĵo ❶, kiu difinas funkcion nomita hello()
. La kodo en la bloko kiu sekvas la def
komunikaĵo ❷ estas la korpo de la funkcio. Tiu kodo estas ekzekutita kiam la funkcio estas nomita, ne kiam la funkcio unue difinitaj.
La
hello()
linioj post la funkcio ❸ estas funkcio alvokoj. En kodo, funkcio alvoko estas simple la funkcio nomo sekvata de krampoj, eventuale kun iom da argumentoj en inter la krampoj. Kiam la programo ekzekuto atingas tiuj alvokoj, ĝi saltos al la supro linio en la funkcio kaj komenci ekzekuti la kodo tie.
Kiam atingas la finon de la funkcio, la ekzekuto revenas al la linio
kiu vokis la funkcio kaj daŭre moviĝas tra la kodo kiel antaŭe.
Ekde tiu programo nomas
hello()
tri fojojn, la kodo en la hello()
funkcio estas plenumata trifoje. Kiam vi kuros ĉi programo, la eligo aspektas jene: Howdy! Howdy !!! Saluton. Howdy! Howdy !!! Saluton. Howdy! Howdy !!! Saluton.
Grava celo funkcioj estas kolekti kodo kiu prenas ekzekutita plurfoje. Sen funkcio difinita, vi devus kopii kaj alglui ĉi tiun kodon ĉiun fojon, kaj la programo aspektus tiel:
presi ( 'Howdy!') presi ( 'Howdy !!!') presi ( 'Saluton tie.') presi ( 'Howdy!') presi ( 'Howdy !!!') presi ( 'Saluton tie.') presi ( 'Howdy!') presi ( 'Howdy !!!') presi ( 'Saluton tie.')
Ĝenerale, vi ĉiam volas eviti duobligante kodon, ĉar se vi iam decidos
ĝisdatigi la kodon-se, ekzemple, vi trovas cimon vi devas
redifini-you'll devas memori ŝanĝi la kodon ĉie vi kopiis ĝin.
Kiel vi ricevas pli programado sperto, vi ofte trovos vin deduplicating kodo, kio signifas akiranta liverita de duobligitaj aŭ kopio-kaj-batitaj kodon. Deduplication faras viaj programoj pli mallongaj, pli facile legi kaj facile ĝisdatigi.
def deklaroj kun Parametroj
Kiam vi vokos la
print()
aŭ len()
funkcio, vi pasas en valoroj, nomita argumentoj en tiu kunteksto, per entajpigo inter la krampoj. Vi povas ankaŭ difini vian propran funkcioj kiuj akceptas argumentojn. Tajpu tiun ekzemplon en la dosiero redaktoro kaj konservi ĝin kiel helloFunc2.py: ❶ def saluton (nomo): ❷ print ( "Saluton" + nomo) ❸ saluton ( "Alicio ') saluton ( 'Bob')
Kiam vi kuros ĉi programo, la eligo aspektas jene:
Saluton Alicia Saluton Bob
La difino de la
hello()
funkcio en tiu programo havas parametron nomita name
❶. Parametro estas variablo kiu argumento estas stokita en kiam funkcio estas nomita. Unuafoje la hello()
funkcio estas nomita, estas kun la argumento 'Alice'
❸. La programo ekzekuto eniras la funkcio kaj la variablo name
estas aŭtomate metita 'Alice'
, kio estas kio akiras presita por la print()
komunikaĵo ❷.
Unu speciala afero noti ĉirkaŭ parametroj estas ke la valoro stokita en parametro estas forgesita kiam la funkcio revenas. Ekzemple, se vi aldonis
print(name)
post hello('Bob')
en la antaŭa programo, la programo donas vin NameError
ĉar ekzistas neniu variablo nomata name
. Tiu variablo estis detruita post la funkcio alvoko hello('Bob')
revenis, do print(name)
devus referi al name
variablo kiu ne ekzistas.
Tio estas simila al kiel programo variabloj estas forgesita kiam la programo finiĝas. Mi parolos pli pri kial tio okazas poste en la ĉapitro, kiam mi diskutas kion funkcia loka medio estas.
Reveni Valoroj kaj reveni Deklaroj
Kiam vi vokos la
len()
funkcio kaj pasi ĝin argumenton kiel 'Hello'
, la funkcio alvoko taksas la entjera valoro 5
, kiu estas la longo de la kordo vi pasis. Ĝenerale, la valoro kiun funkcio alvoko taksas al nomiĝas la reveno valoro de la funkcio.
Kiam kreanta funkcio uzante la
def
deklaro, vi povas specifi kion la reveno valoro devus esti kun return
deklaro. A return
deklaro konsistas el la sekvaj: - La
return
ŝlosilvorto - La valoro aŭ esprimo kiu la funkcio devus reveni
Kiam esprimo estas uzita kun
return
deklaro, la reveno valoro estas kion tiu esprimo taksas al. Ekzemple, la sekvanta programo difinas funkcion kiu resendas malsamaj kordoj depende kion nombro estas pasita kiel argumento. Tajpi tiun kodon en la dosiero redaktoro kaj konservi ĝin kiel magic8Ball.py: ❶ importi hazarda ❷ def getAnswer (answerNumber): ❸ se answerNumber == 1: reveni 'Estas certaj' elif answerNumber == 2: reveni 'Estas tute certe' elif answerNumber == 3: reveno 'Jes' elif answerNumber == 4: reveno 'Respondu nebula reprovu' elif answerNumber == 5: reveni Petu pli posta ' elif answerNumber == 6: reveni 'Koncentri kaj demandas denove' elif answerNumber == 7: reveni Mia respondo estas ne ' elif answerNumber == 8: reveni 'Outlook ne tiel bona' elif answerNumber == 9: reveni "Tre malcerta ' ❹ r = random.randint (1, 9) ❺ fortuno = getAnswer (r) ❻ print (fortuno)
Kiam tiu programo komenciĝas, Python unua importas la
random
modulo ❶. Tiam la getAnswer()
funkcio estas difinita ❷. Ĉar la funkcio estas difinita (kaj ne nomita), la ekzekuto saltas super la kodon en ĝi. Tuj poste, la random.randint()
funkcio estas nomita kun du argumentoj, 1
kaj 9
❹. Ĝi taksas al hazarda entjero inter 1
kaj 9
(Inkluzivanta 1
kaj 9
si mem), kaj ĉi tiu valoro estas stokita en variablo nomata r
.
La
getAnswer()
funkcio estas nomita kun r
kiel la argumento ❺. La programo ekzekuto movas al la supro de la getAnswer()
funkcio ❸ kaj la valoro r
estas stokita en parametro nomita answerNumber
. Tiam, laŭ tiu valoro en answerNumber
, la funkcio redonas unu el multaj eblaj ŝnuro valoroj. La programo ekzekuto revenas al la linio ĉe la fundo de la programo kiu origine nomis getAnswer()
❺. La liverita ĉeno estas atribuita al variablo nomata fortune
, kiu tiam gets pasis al print()
vokas ❻ kaj estas presita al la ekrano.
Notu ke kiam vi povas pasi reveno valoroj kiel argumento por alia funkcio alvoko, vi povus mallongigi tiujn tri liniojn:
r = random.randint (1, 9) fortuno = getAnswer (r) print (fortuno)
al tiu sola ekvivalenta linio:
print (getAnswer (random.randint (1, 9)))
Memoru, esprimoj estas formitaj de valoroj kaj operatoroj. Funkcio alvoko povas esti uzita en esprimo ĉar ĝi taksas al lia reveno valoro.
La Neniu Valoro
En Python estas valoro nomita
None
, kiu reprezentas la manko de valoro. None
estas la sola valoro de la NoneType
datumtipo. (Aliaj programlingvoj povus nomi tiun valoron null
, nil
aŭ undefined
.) Ĝuste kiel la Bulea True
kaj False
valoroj, None
devas esti tajpita kun majuskla N.
Tiu valoro sen-po-valoro povas esti helpema kiam vi devas gardi iun kiu ne estos konfuzita por reala valoro en variablo. Unu loko
None
estas uzata kiel la reveno valoro de print()
. La print()
funkcio vidigas tekston sur la ekrano, sed ĝi ne bezonas reveni ion en la sama maniero len()
aŭ input()
faras. Sed ĉar ĉiu funkcio alvokoj devas taksi al reveno valoro, print()
redonas None
. Vidi tion en ago, eniri la sekva en la interaga konko: >>> Spamado = print ( 'Saluton!') Saluton! >>> Neniu == spamon veraj
Malantaŭ la scenoj, Pitono aldonas
return None
al la fino de ajna funkcio difino sen return
deklaro. Tio estas simila al kiel while
aŭ for
buklo implice finiĝas per continue
deklaron. Ankaŭ, se vi uzas return
deklaro sen valoro (te, nur la return
ŝlosilvorton per sin), tiam None
estas redonita. Temo Argumentoj kaj presita ()
Plej argumentoj estas identigitaj per sia pozicio en la funkcio nomita. Ekzemple,
random.randint(1, 10)
estas malsama random.randint(10, 1)
. La funkcio alvoko random.randint(1, 10)
revenos hazarda entjero inter 1
kaj 10
, ĉar la unua argumento estas la malalta fino de la intervalo kaj la dua argumento estas la alta fino (dum random.randint(10, 1)
kaŭzas eraro).
Tamen, ŝlosilvorto argumentoj estas identigitaj per la ŝlosilvorto metis antaux ili la funkcio nomita. Ŝlosilvorto argumentoj estas ofte uzita por laŭvolaj parametroj. Ekzemple, la
print()
funkcio havas la laŭvolaj parametroj end
kaj sep
specifi kion devus esti presita ĉe la fino de liaj argumentoj kaj inter liaj argumentoj (disigante ilin), respektive.
Se vi kuris la sekvan programon:
print ( 'Saluton') print ( 'Mondo)
la eligo aspektus tiel:
saluton mondo
La du kordoj aperas sur apartaj linioj ĉar la
print()
funkcio aŭtomate aldonas novan linion karakteron al la fino de la ŝnuro estas pasita. Tamen, vi povas agordi la end
ŝlosilvorto argumento ŝanĝi tiun al alia linio. Ekzemple, se la programo estis jena: print ( 'Saluton', fino = '') print ( 'Mondo)
la eligo aspektus tiel:
Saluton mondo
La eligo estas presitaj sur ununura linio ĉar ne plu nova linio presis post
'Hello'
. Anstataŭe, la malplenan ĉenon estas presita. Tio estas utila se vi devas malŝalti la linion kiu akiras aldonita al la fino de ĉiu print()
funkcion alvoko.
Simile, kiam vi transiros multoblaj kordoj valoroj por
print()
, la funkcio aŭtomate apartigos ilin kun sola spaco. Eniri la sekva en la interaga konko: >>> Print ( 'katoj', 'hundoj', 'musoj') katoj hundoj musoj
Sed vi povus anstataŭigi la defaŭltan disigante ŝnuro aprobante la
sep
ŝlosilvorto argumento. Eniri la sekva en la interaga konko: >>> Print ( 'katoj', 'hundoj', 'musoj', Sep = '') katoj, hundoj, musoj
Vi povas aldoni ŝlosilvorto argumentojn al funkcioj vi skribas tiel,
sed unue vi devos lerni pri la listo kaj vortaro datumtipoj en la
venontaj du ĉapitroj.
Nuntempe nur scias ke kelkaj funkcioj havas laŭvolan ŝlosilvorto
argumentoj kiuj povas esti precizigita kiam la funkcio estas nomita.
Loka kaj Tutmonda Medio
Parametroj kaj variabloj kiuj estas atribuitaj en nomita funkcio laŭdire ekzistas en tiu funkcio la loka medio. Variabloj kiuj estas atribuitaj ekster ĉiuj funkcioj laŭdire ekzistas en la tutmonda medio. Variablo kiu ekzistas en loka amplekso estas nomata loka variablo, dum variablon kiu ekzistas en la tutmonda amplekso nomata tutmonda variablo. A variablo devas esti unu aŭ la alia; ĝi ne povas esti ambaŭ lokaj kaj sumaj.
Pensu pri medio kiel ujo por variabloj. Kiam medio estas detruita, ĉiuj valoroj stokitaj en la medio de la variabloj estas forgesita. Ekzistas nur unu tutmonda amplekso, kaj ĝi estas kreita kiam via programo komencas. Kiam via programo finiĝas, la tutmonda amplekso estas detruita, kaj ĉiuj ĝiaj variabloj estas forgesita. Alie, la venontan fojon vi kuris via programo, la variabloj memorus iliajn valorojn de la lasta tempo vi kuris ĝin.
Loka amplekso estas kreita kiam funkcio estas nomita. Ajna variabloj atribuita en tiu funkcio ekzistas en la loka medio. Kiam la funkcio revenas, la loka amplekso estas detruita, kaj tiuj variabloj estas forgesita.
La venontan fojon vi nomas tiun funkcion, la lokaj variabloj ne memoras
la valoroj stokitaj en ili de la lasta tempo la funkcio vokita.
Medioj gravas por pluraj kialoj:
- Kodo en la tutmonda amplekso povas uzi ajnan lokajn variablojn.
- Tamen, loka amplekso povas aliri tutmonda variabloj.
- Kodo en funkcio de loka amplekso povas uzi variablojn en ajna alia loka medio.
- Vi povas uzi la saman nomon por malsamaj variabloj se ili estas en malsamaj medioj. Tio estas, ne povas esti loka variablo nomata
spam
kaj tutmonda variablo ankaŭ nomitaspam
.
La kialo Python havas malsamajn mediojn anstataŭ simple fari cxion
tutmonda variablo estas tiel ke kiam variabloj estas modifitaj de la
kodo en aparta alvoko al funkcio, la funkcio interagas kun la resto de
la programo nur per liaj parametroj kaj la reveno valoro. Ĉi striktas malsupren la liston kodo linioj kiuj povas kaŭzi misfunkciadon.
Se via programo enhavis nenion krom tutmonda variabloj kaj havis cimon
pro ŝanĝiĝema estulo metita malbonan valoron, tiam estus malfacile spuri
kie tiu malbona valoro estis fiksita. Ĝi povus esti tuj de ie ajn en la programo-kaj via programo povus esti centoj aŭ miloj da linioj longaj! Sed se la cimo estas pro loka variablo kun malbona valoro, sciu ke nur la kodon en tiu funkcio povus agordi ĝin malĝuste.
Uzante tutmonda variabloj en malgrandaj programoj estas bone, ĝi estas
malbona kutimo fidi tutmonda variabloj kiel viaj programoj akiri pli kaj
pli granda.
Lokaj variabloj Ne Be Used en la Tutmonda Medio
Konsideras ĉi programo, kiu kaŭzos eraron kiam vi kuros ĝin:
def spamado (): ovojn = 31337 spamo() print (ovojn)
Se vi kuros ĉi programo, la eligo aspektos tiel ĉi:
Traceback (plej lasta alvoko lasta): Dosiera "C: /test3784.py", linio 4, en <modulo> print (ovojn) NameError: nomo ovojn 'ne estas difinita
La eraro okazas pro la
eggs
variablo ekzistas nur en la regiona medio kreita kiam spam()
estas nomita. Iam la programo ekzekuto revenas de spam
, ke loka amplekso estas detruita, kaj ne plu variablo nomata eggs
. Do kiam via programo provas kuri print(eggs)
, Python donas eraro diri ke eggs
ne estas difinita. Tio havas sencon se vi pensas pri ĝi; Kiam la programo ekzekuto estas en la tutmonda amplekso, neniu loka medioj ekzistas, do ne povas esti ajna loka variabloj. Tial nur tutmonda variabloj povas esti uzata en la tutmonda medio. Lokaj Medioj Ne Uzu Variabloj en Aliaj lokaj Medioj
Nova loka amplekso estas kreita kiam funkcio estas nomita, inkluzive kiam funkcio estas nomita de alia funkcio. Konsideras ĉi programo:
def spamado (): ❶ ovojn = 99 ❷ lardo () ❸ print (ovojn) def lardo (): ŝinko = 101 ❹ ovojn = 0 ❺ spamado ()
Kiam la programo komenciĝas, la
spam()
funkcio estas nomita ❺ kaj loka amplekso estas kreita. La loka variablo eggs
❶ enkadriĝas al 99
. Tiam la bacon()
funkcio estas nomita ❷ kaj duan lokan medion kreita. Multnombraj lokaj medioj povas ekzisti samtempe. En tiu nova loka medio, la loka variablo ham
estas agordita 101
, kaj loka variablo eggs
-kiu estas malsama de la en spam()
's lokan amplekson-ankaŭ kreis ❹ kaj starigis al 0
.
Kiam
bacon()
redonas la lokan medion por ke alvoko estas detruita. La programo ekzekuto daŭre en la spam()
funkcio por presi la valoro de eggs
❸, kaj ekde la lokan amplekson por la alvoko al spam()
ankoraŭ ekzistas tie, la eggs
variablo estas agordita 99
. Jen kion la programo presaĵoj.
La konkludo estas ke lokaj variabloj en unu funkcio estas tute aparta de la lokaj variabloj en alia funkcio.
Tutmonda variabloj povas legi de Loka Medio
Konsideru la sekvan programon:
def spamado (): print (ovojn) ovojn = 42 spamo() print (ovojn)
Ĉar ne ekzistas parametro nomita
eggs
aŭ ajna kodo kiu atribuas eggs
valoron en la spam()
funkcio, kiam eggs
estas uzata en spam()
, Python konsideras ĝin aludo al la tutmonda variablo eggs
. Tial 42
estas presitaj kiam la antaŭa programo kuras. Loka kaj Suma Variabloj kun la sama nomo
Simpligi vian vivon, eviti uzi loka variabloj kiuj havas la saman nomon kiel tutmonda variablo aŭ alia loka variablo. Sed teknike, ĝi estas perfekte leĝa fari tion en Python. Por vidi kio okazas, tajpu la sekvan kodon en la dosiero redaktoro kaj konservi ĝin kiel sameName.py:
def spamado (): ❶ ovojn = 'spamado lokaj' print (ovojn) # impresoj 'spamado lokaj' def lardo (): ❷ ovojn = 'lardo lokaj' print (ovojn) # impresoj 'lardo lokaj' spamo() print (ovojn) # impresoj 'lardo lokaj' ❸ ovojn = 'tutmonda' lardo () print (ovojn) # impresoj 'tutmonda'
Kiam vi kuros ĉi programo, ĝi eligas la jenajn:
lardo loka spamado loka lardo loka tutmonda
Estas fakte tri malsamaj variabloj en tiu programo, sed konfuze ili ĉiuj nomis
eggs
. La variabloj estas kiel sekvas:
❶ Variablo nomita
eggs
kiuj ekzistas en loka amplekso kiam spam()
estas nomita.
❷ Variablo nomita
eggs
kiuj ekzistas en loka amplekso kiam bacon()
estas nomita.
❸ Variablo nomita
eggs
kiuj ekzistas en la tutmonda medio.
Ĉar tiuj tri apartaj variabloj ĉiuj havas la saman nomon, ĝi povas esti
konfuza por konservi trako de kiu unu estas uzata ĉe ajna donita
tempon. Jen kial vi devus eviti uzi la saman variablo nomo en malsamaj medioj.
La tutmonda Deklaro
Se vi bezonas modifi tutmonda variablo ene funkcio, uzi la
global
komunikaĵo. Se vi havas linion kiel global eggs
ĉe la supro de funkcio, ĝi diras Python, "En tiu funkcio, eggs
rilatas al la tutmonda variablo, do ne krei lokan variablon kun tiu
nomo." Ekzemple, tajpu la sekvan kodon en la dosiero redaktoro kaj
konservi ĝin kiel sameName2.py: def spamado (): ❶ tutmonda ovojn ❷ ovojn = 'spamado' ovojn = 'tutmonda' spamo() print (ovojn)
Kiam vi kuros ĉi programo, la fina
print()
alvoko volo eligo ĉi: spamo
Ĉar
eggs
estas deklarita global
ĉe la supro de spam()
❶, kiam eggs
estas agordita 'spam'
❷, tiu tasko estas farita al la tutmonde scoped eggs
. Neniu loka eggs
variablo estas kreita.
Estas kvar reguloj diri ĉu variablo estas en loka amplekso aŭ tutmonda medio:
- Se variablo estas uzata en la tutmonda medio (te, ekster ĉiuj funkcioj), tiam ĝi estas ĉiam tutmonda variablo.
- Se estas
global
deklaro por tiu variablo en funkcio, ĝi estas tutmonda variablo. - Alie, se la variablo estas uzata en asigno deklaro en la funkcio, ĝi estas loka variablo.
- Sed se la variablo estas uzata en asigno deklaro, ĝi estas tutmonda variablo.
Por pli bone senti tiujn regulojn, jen ekzemplo programo. Tajpi la sekvan kodon en la dosiero redaktoro kaj konservi ĝin kiel sameName3.py:
def spamado (): ❶ tutmonda ovojn ovojn = 'spamado' # ĉi tiu estas la tutmonda def lardo (): ❷ ovojn = 'lardo' # ĉi estas loka def ŝinko (): ❸ print (ovojn) # ĉi tiu estas la tutmonda ovojn = 42 # ĉi tiu estas la tutmonda spamo() print (ovojn)
En la
spam()
funkcio, eggs
estas la tutmonda eggs
variablo, ĉar ekzistas global
deklaro por eggs
komence de la funkcio ❶. En bacon()
, eggs
estas loka variablo, ĉar estas asigno komunikaĵo por ĝi en tiu funkcio ❷. En ham()
❸, eggs
estas la tutmonda variablo, ĉar ekzistas neniu asigno komunikaĵo aŭ global
deklaro por ĝi en tiu funkcio. Se vi kuras sameName3.py, la eligo aspektos tiel ĉi: spamo
En funkcio, ŝanĝiĝema estos ĉu ĉiam tutmonda aŭ ĉiam esti loka. Ekzistas neniu maniero ke la kodo en funkcio povas uzi lokan variablon nomita
eggs
kaj tiam poste en tiu sama funkcio uzas la ĝeneralan eggs
variablo. noto
Se vi iam volas modifi la valoron stokita en tutmonda variablo de en funkcio, vi devas uzi
global
deklaron en tiu variablo.
Se vi provas uzi lokan variablon en funkcio al vi atribui valoron al ĝi, kiel en la jena programo, Python donos vin eraro. Vidi tiun, tajpi la sekva en la dosiero redaktoro kaj konservi ĝin kiel sameName4.py:
def spamado (): print (ovojn) # ERROR! ❶ ovojn = 'spamado lokaj' ❷ ovojn = 'tutmonda' spamo()
Se vi trafos la antaŭa programo, ĝi produktas eraron mesaĝo.
Traceback (plej lasta alvoko lasta): Dosiera "C: /test3784.py", linio 6, en <modulo> spamo() Dosiero "C: /test3784.py", linio 2, en spamon print (ovojn) # ERROR! UnboundLocalError: loka variablo ovojn 'referencita antaŭ asigno
Tiu eraro okazas ĉar Pitono vidas ke tie estas asigno komunikaĵo por
eggs
en la spam()
funkcio ❶ kaj tial konsideras eggs
esti loka. Sed ĉar print(eggs)
estas ekzekutita antaŭ eggs
ricevas ion, la loka variablo eggs
ne ekzistas. Python ne fali reen al uzante la tutmondan eggs
variablo ❷. escepto Handling
Nun, ricevas eraron, aŭ escepto, en via Python programo signifas la tutan programon kraŝos. Vi ne volas ke tio okazu en reala mondo programojn. Anstataŭe, vi volas ke la programo por detekti erarojn, manipuli ilin, kaj tiam daŭrigi kuri.
Ekzemple, konsideru la sekvan programon, kiu havas "dislimo-de-nul" eraro. Malfermi novan dosieron redaktanto fenestro kaj eniri la sekvan kodon, ŝparante ĝin kiel zeroDivide.py:
def spamado (divideBy): reveni 42 / divideBy print (spamado (2)) print (spamado (12)) print (spamado (0)) print (spamado (1))
Ni difinis funkcion nomita
spam
, destinis parametro, kaj poste presas la valoron de tiu funkcio kun diversaj parametroj por vidi kio okazas. Tio estas la eligo vi ricevas kiam vi kuros la antaŭa kodo 21.0 3.5 Traceback (plej lasta alvoko lasta): Dosiero "C: /zeroDivide.py", linio 6, en <modulo> print (spamado (0)) Dosiera "C: /zeroDivide.py", linio 2, en spamon reveni 42 / divideBy ZeroDivisionError: divido per nulo
A
ZeroDivisionError
okazas kiam vi provas dividi kelkaj de nulo. De la numero de linioj donitaj en la erarmesaĝo, vi scias, ke la return
deklaro en spam()
kaŭzas eraron.
Eraroj povas esti manipulita per
try
kaj except
deklaroj. La kodo kiu povus potenciale havas eraron estas metita en try
klaŭzo. La programo ekzekuto movas al la komenco de jena except
klaŭzo se eraro okazas.
Vi povas meti la antaŭa divido-per-nula kodon en
try
klaŭzo kaj havas except
klaŭzo enhavas kodon por manipuli kio okazas kiam tiu eraro okazas. def spamado (divideBy): provu: reveni 42 / divideBy krom ZeroDivisionError: print ( 'Eraro: Nevalida argumento.) print (spamado (2)) print (spamado (12)) print (spamado (0)) print (spamado (1))
Kiam kodon en
try
klaŭzo kaŭzas eraro, la programo ekzekuto tuj movas al la kodo en la except
klaŭzo. Post kuri tiu kodo, la ekzekuto daŭrigas kiel normala. La eligo de la antaŭa programo estas kiel sekvas: 21.0 3.5 Eraro: Nevalida argumento. neniu 42.0
Notu ke neniu eraroj kiuj okazas en funkcio alvokoj en
try
bloki ankaŭ estos kaptitaj. Konsideru la sekvan programon, kiu anstataŭe havas la spam()
nomas en la try
bloko: def spamado (divideBy): reveni 42 / divideBy provu: print (spamado (2)) print (spamado (12)) print (spamado (0)) print (spamado (1)) krom ZeroDivisionError: print ( 'Eraro: Nevalida argumento.)
Kiam tiu programo kuras, la eligo aspektas jene:
21.0 3.5 Eraro: Nevalida argumento.
La kialo
print(spam(1))
estas neniam ekzekutita estas ĉar iam la ekzekuto saltas al la kodo en la except
klaŭzo, ĝi ne revenas al la try
klaŭzo. Anstataŭe, ĝi nur daŭras movi malsupren kiel normalaj. Mallonga Programo: Divenu la Nombro
La ludilo ekzemploj mi havas al vi ĝis nun estas utila por enkonduki
bazaj konceptoj, sed nun ni vidos kiel ĉio vi lernis kunfluas en pli
kompletan programon. En tiu sekcio, mi montros al vi simplan "diveni la numeron" ludo. Kiam vi kuros ĉi programo, la eligo aspektos ion kiel jene:
Mi pensas pri kelkaj inter 1 kaj 20. Preni diveni. 10 Via konjekto estas tro malalta. Preni diveni. 15 Via konjekto estas tro malalta. Preni diveni. 17 Via konjekto estas tro alta. Preni diveni. 16 Bona laboro! Vi divenis mian numeron en 4 divenoj!
Tajpi la sekvan fontkodon en la dosiero redaktoro kaj konservi la dosieron kiel guessTheNumber.py:
# Jen diveno la nombro ludo. importado hazarda secretNumber = random.randint (1, 20) print ( 'Mi pensas pri kelkaj inter 1 kaj 20.) # Petu la ludanto diveni 6 fojojn. por guessesTaken en gamo (1, 7): presi ( 'Prenu diveni.') diveni = int (enigo ()) se diveno <secretNumber: print ( 'Via konjekto estas tro malalta. ") elif diveni> secretNumber: print ( 'Via konjekto estas tro alta.') alie: rompi # Ĉi tiu kondiĉo estas la ĝusta diveno! se diveni == secretNumber: print ( 'Bona laborposteno! Vi divenis mian numeron en' + str (guessesTaken) + 'divenoj!') alie: print ( 'Nope. La nombro mi pensis pri estis' + str (secretNumber))
Ni rigardu ĉi kodo linio por linio, komencante ĉe la supro.
# Jen diveno la nombro ludo. importado hazarda secretNumber = random.randint (1, 20)
Unue komenton ĉe la supro de la kodo klarigas kion la programo faras. Tiam, la programo importas la
random
modulo por ke ĝi povas uzi la random.randint()
funkcio por generi numeron por la uzanto diveni. La reveno valoro, hazarda entjero inter 1 kaj 20, estas stokita en la variablo secretNumber
. print ( 'Mi pensas pri kelkaj inter 1 kaj 20.) # Petu la ludanto diveni 6 fojojn. por guessesTaken en gamo (1, 7): presi ( 'Prenu diveni.') diveni = int (enigo ())
La programo rakontas la ludanto ke ĝi supreniru kun sekreta nombro kaj donos la ludanton ses ŝancojn diveni ĝin. La kodo kiu permesas la ludanton eniri diveno kaj ĉekojn kiuj diveni estas en
for
buklo kiu volas buklo maksimume ses fojojn. La unua kiu okazas en la buklo estas ke la ludanto tipoj en diveno. Ekde input()
redonas kordoj, lia reveno valoro estas pasita rekte en int()
, kiu tradukas la kordo en entjero valoro. Tiu akiras entenita en variablo nomata guess
. se diveno <secretNumber: print ( 'Via konjekto estas tro malalta. ") elif diveni> secretNumber: print ( 'Via konjekto estas tro alta.')
Tiuj malmultaj linioj de kodo ĉeko por vidi ĉu la diveno estas malpli ol aŭ pli granda ol la sekreta nombro. Ambaŭkaze, aludo estas presita al la ekrano.
alie: rompi # Ĉi tiu kondiĉo estas la ĝusta diveno!
Se la konjekto estas nek superaj nek malsuperaj al la sekreta nombro,
tiam ĝi devas esti egala al la sekreta numero, en kiu kazo vi deziras la
programo ekzekuto por rompi la
for
buklo. se diveni == secretNumber: print ( 'Bona laborposteno! Vi divenis mian numeron en' + str (guessesTaken) + 'divenoj!') alie: print ( 'Nope. La nombro mi pensis pri estis' + str (secretNumber))
Post la
for
buklo, la antaŭa if...else
aserto ĉekojn ĉu la ludanto ĝuste divenis la numeron kaj presas taŭgan mesaĝon por la ekrano. En ambaŭ kazoj, la programo montras variablon kiu enhavas entjero valoro ( guessesTaken
kaj secretNumber
). Ĉar ĝi devas concatenate tiuj entjero valoroj por kordoj, sekvinbero tiuj variabloj al la str()
funkcio, kiu redonas la kordoj valoro formo de tiuj entjeroj. Jen kordoj povas kroĉitaj kun la +
operatoroj antaŭ finfine esti pasita al la print()
funkcion alvoko. resumo
Funkcioj estas la ĉefa vojo al compartmentalize vian kodon en logikaj grupoj.
Ekde la variabloj en funkcioj ekzistas en siaj propraj lokaj medioj, la
kodo en funkcio ne povas rekte influi la valorojn de variabloj en aliaj
funkcioj. Tio limigas kion kodo povus ŝanĝi la valorojn de viaj variabloj, kiuj povas esti helpema kiam temas elpurigi vian kodon.
Funkcioj estas granda ilo por helpi vin organizi vian kodon.
Vi povas pensi pri ili kiel nigraj skatoloj: Ili havas enigoj en la
formo de parametroj kaj eliroj en la formo de reveno valoroj, kaj la
kodo en ili ne tuŝas variabloj en aliaj funkcioj.
En antaŭaj ĉapitroj, sola eraro povas kaŭzi vian programoj kraŝi. En ĉi tiu ĉapitro, vi lernis pri
try
kaj except
deklaroj, kiu povas kuri kodo kiam eraro estis detektita. Tio povas fari viajn programojn pli rezistema al komuna eraro kazoj. praktiko Demandoj
Q:
|
1. Kial funkcioj avantaĝa havi en viaj programoj?
|
Q:
|
2. Kiam faras la kodon en funkcio ekzekuti: kiam la funkcio estas difinita aŭ kiam la funkcio estas nomata?
|
Q:
|
3. Kio deklaro kreas funkcio?
|
Q:
|
4. Kio estas la diferenco inter funkcio kaj funkcio alvokon?
|
Q:
|
5. Kiom da tutmondaj medioj estas en Python programo? Kiom da lokaj medioj?
|
Q:
|
6. Kio okazas al variabloj en loka amplekso kiam la funkcio alvoko revenas?
|
Q:
|
7. Kio estas reveno valoro? Povas reveno valoro estos parto de esprimo?
|
Q:
|
8. Se funkcio ne havas return, kio estas la reveno valoro de alvoko al tiu funkcio?
|
Q:
|
9. Kiel vi povas devigi ŝanĝiĝema en funkcio por rilati al la tutmonda variablo?
|
Q:
|
10. Kio estas la datumtipo de
None ? |
Q:
|
11. Kion la
import areallyourpetsnamederic komunikaĵo fari? |
Q:
|
12. Se vi havas funkcion nomita
bacon() en modulo nomita spam , kiel vi nomas ĝin post importanta spam ? |
Q:
|
13. Kiel vi povas preventi programon de kraŝanta kiam alvenas eraro?
|
Q:
|
14. Kio iras sur la
try klaŭzo? Kio okazas en la except klaŭzo? |
praktiko Projektoj
Por praktiko, skribi programojn por fari la sekvajn taskojn.
La _Collatz_ Sekvenco
Skribi funkcion nomis
collatz()
kiu havas parametron nomita number
. Se number
estas para, tiam collatz()
devus presi number // 2
kaj revenos ĉi valoron. Se number
estas nepara, tiam collatz()
devus presi kaj revenos 3 * number + 1
.
Tiam skribi programon kiu permesas la uzanton tipo en entjera kaj kiu gardas nomante
collatz()
en tiu nombro ĝis la funkcio redonas la valoron 1
.
(Mirinde sufiĉa, ĉi vico efektive funkcias por ajna entjero-malpli
frue, per tiu vico, vi alvenos je 1! Eĉ matematikistoj ne certas kial.
Via programo estas esplori kio nomiĝas la _Collatz_ sekvenco, kelkfoje nomita "la plej simpla neeblaj matematikaj problemo. ")
Memoru konverti la reveno valoro de
input()
al entjero kun la int()
funkcion; alie, ĝi estos ŝnuro valoron.
Konsileto: Entjera
number
estas eĉ se number % 2 == 0
, kaj ĝi estas nepara se number % 2 == 1
.
La eligo de ĉi tiu programo povus rigardi ion tiel:
Entajpu numeron: 3 10 5 16 8 4 2 1
Eniro Validigo
Aldoni
try
kaj except
deklaroj al la antaŭa projekto por detekti ĉu la uzanto tajpas en noninteger ŝnuro. Kutime, la int()
funkcion levos ValueError
eraro se ĝi pasis noninteger ĉeno, kiel en int('puppy')
. En la except
klaŭzo, presi mesaĝon al la uzanto por diri ili devas eniri entjero.
Nenhum comentário:
Postar um comentário