Python-ի միջին մակարդակ

Փոփոխելի(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-ը որպես լռելյայն արժեք և անհրաժեշտության դեպքում ստեղծել նոր օբյեկտ ֆունկցիայում:
 
To check your solution you need to sign in
Sign in to continue