Փոփոխելի(mutable) լռելյայն արգումենտներ
Երբ դուք խառնում եք փոփոխական արգումենտները Python-ում լռելյայն արգումենտների հետ, դա կարող է հանգեցնել որոշ անսպասելի արդյունքների:
Եկեք սա բացատրենք պարզ օրինակով. Ենթադրենք՝ դուք ուսուցիչ եք և ցանկանում եք ստեղծել մի ֆունկցիա՝ տարբեր առաջադրանքների համար աշակերտի միավորները գրանցելու համար: Ցանկանում եք օգտագործել ցուցակ, որպեսզի հետևեք այս միավորներին: Այսպիսով, դուք կարող եք սկզբում գրել այսպիսի բան.
def record_score(new_score, score_list=[]):
score_list.append(new_score)
return score_list
print(record_score(95)) # [95]
print(record_score(85)) # [95, 85]
Սա կարծես թե լավ է աշխատում:
record_score
ֆունկցիան ընդունում է միավոր և ցուցակ: Եթե ցուցակը չի տրամադրվում, այն օգտագործում է դատարկ ցուցակ (ֆունկցիայի սահմանման մեջ score_list=[]
):Երբ կանչում եք
record_score(95)
, թվում է, թե ֆունկցիան ճիշտ է աշխատում. այն վերադարձնում է ցուցակ 95 միավորով: Բայց երբ այնուհետև կանչում եք record_score(85)
, ֆունկցիան վերադարձնում է ցուցակ 95-ով և 85-ով: Կարծես ֆունկցիան հիշում էր վերջին անգամ կանջածից հետո ցուցակը:Սա կարող է ստիպել ձեզ մտածել: Ծրագրավորման լեզուներից շատերում, երբ ֆունկցիան ավարտվում է, նրա բոլոր լոկալ փոփոխականները (ինչպես
score_list
) ջնջվում են և մոռացվում: Հաջորդ անգամ, երբ գործառույթը կանչվի, այն նորից է սկսվում:Բայց Python-ում վարքագիծը տարբերվում է, երբ փոփոխական օբյեկտն օգտագործվում է որպես լռելյայն արգումենտ։ Python-ը լռելյայն արգումենտը ստեղծում է միայն մեկ անգամ, երբ գործառույթը սահմանվում է: Այսպիսով, ամեն անգամ, երբ դուք կանչում եք
record_score
-ն՝ առանց ցուցակ տրամադրելու, Python-ն օգտագործում է նույն ցուցակը, որը ստեղծել է ֆունկցիան առաջին անգամ սահմանելիս: Եթե դուք փոփոխում եք այդ ցուցակը (ավելացնելով միավոր), փոփոխությունը մնում է:Այսպիսով, մեր ֆունկցիայում
score_list
-ը համօգտագործվում է բոլոր ֆունկցիայի կանչերի հետ, որտեղ մենք չենք տրամադրում մեր ցուցակը: Ահա թե ինչու մեր օրինակում միավորները ավելանում են:Սա այն չէ, ինչ մենք ուզում էինք: Մենք ցանկանում էինք, որ յուրաքանչյուր
record_score
-ի կանչ սկսվեր դատարկ ցուցակով, եթե մենք չտրամադրեինք մեր սեփական ցուցակը:Սրանից խուսափելու համար սովորական պրակտիկա է
None
-ը որպես լռելյայն արժեք օգտագործել արգումենտների համար, որոնք կարող են փոփոխական լինել: Այնուհետև ֆունկցիայի ներսում կարող եք ստեղծել նոր փոփոխվող օբյեկտ, եթե արգումենտը None
է: Ահա թե ինչպես կարող եք գրել record_score
ֆունկցիան՝ խնդրից խուսափելու համար.def record_score(new_score, score_list=None):
if score_list is None: # If no list was provided,
score_list = [] # create a new one
score_list.append(new_score)
return score_list
print(record_score(95)) # [95]
print(record_score(85)) # [85]
Այս շտկված տարբերակում
record_score
-ի յուրաքանչյուր կանչ, որը չի փոխանցում իր սեփական ցուցակը, ստանում է բոլորովին նոր ցուցակ: Այսպիսով, միավորները չեն մնում ֆունկցիայի կանչերի միջև:💡
Այսպիսով, հիմնական միջոցը սա է.
Փոփոխական լռելյայն արգումենտները Python-ում կարող են հանգեցնել անսպասելի վարքի, քանի որ դրանք ստեղծվում են միայն մեկ անգամ, և նույն օբյեկտն օգտագործվում է ամեն անգամ, երբ ֆունկցիան կանչվում է: Սա կարող է չլինել ձեր ուզածը, հատկապես երբ փոփոխում եք փոփոխվող օբյեկտը: Այս խնդրից խուսափելու համար կարող եք օգտագործել
None
-ը որպես լռելյայն արժեք և անհրաժեշտության դեպքում ստեղծել նոր օբյեկտ ֆունկցիայում: