چالش روزانه · ۲۲ مهر ۱۴۰۵
چالش پایتون ۲: متغیری که هم هست و هم نیست
قبل از اجرای کد، خروجی آن را پیشبینی کن. حدس نزن؛ خط به خط فکر کن پایتون چه میکند.
x = 10
def show():
print(x)
x = 20
show()نمایش پاسخ و توضیح
پاسخ درست: گزینهٔ ج — UnboundLocalError
چرا ۱۰ چاپ نمیشود؟
تصمیم دربارهٔ اینکه یک نام محلی است یا سراسری، هنگام اجرای تابع گرفته نمیشود؛ پایتون آن را هنگام کامپایل بدنهٔ تابع میگیرد.
چون داخل show جایی x = 20 آمده، پایتون x را برای کل تابع یک متغیر محلی در نظر میگیرد؛ حتی برای خطهایی که قبل از آن انتساب هستند. بنابراین print(x) میخواهد x محلی را بخواند که هنوز مقداری نگرفته است و نتیجه خطای زیر است:
UnboundLocalError: cannot access local variable 'x' where it is not associated with a value
این NameError نیست، چون نام x وجود دارد؛ فقط هنوز به مقداری «بسته» (bound) نشده است. (UnboundLocalError در واقع زیرکلاس NameError است، اما پیام دقیق همان اولی است.)
راهحلها
اگر واقعاً میخواهید متغیر سراسری را تغییر دهید، از global استفاده کنید؛ هرچند بهتر است مقدار را از ورودی بگیرید و با return برگردانید:
x = 10
def show():
global x
print(x)
x = 20
show()
print(x)
حالا خودت اجرا کن و تغییرش بده
x = 10
def show():
print(x)
x = 20
show()