مقدمه

بر خلاف خیلی از زبان‌های برنامه‌نویسی که از آکلادها برای ایجاد بلاک در کد استفاده می‌کنند، پایتون از تورفتگی (indentation) به این منظور استفاده می‌کند. برای نمونه، در مثال‌های درس قبل دیدیم که چطور برای ایجاد بلاک مربوط به یک حلقه‌ی for از تورفتگی استفاده می‌شود. اتکای پایتون به تورفتگی به افزایش خوانایی برنامه کمک می‌کند اما در عین حال، باید مراقب برخی اشتباهات رایج مربوط به تورفتگی هم باشیم. در این درس نگاهی خواهیم داشت به این قبیل اشتباهات و راه‌کارهایی را برای جلوگیری از بروز آنها ارائه می‌دهیم.

فراموش کردن تورفنگی

یکی از رایج‌ترین اشتباهات مربوط به تورفتگی این است که حایی که نیاز به تورفتگی است (مثلاً بعد از گزاره‌ی for)، تورفتگی ایجاد نکنیم. در صورتی که این اشتباه را مرتکب شویم، پایتون به ما یادآوری می‌کند که باید تورفتگی را ایجاد کنیم. کد زیر را در فایلی به نام magicians.py وارد کنید.

Copy Icon magicians.py
magicians = ['alice', 'david', 'carolina'] 
for magician in magicians: 
print(magician)

در اینجا باید بعد از گزاره‌ی for تورفتگی ایجاد شود تا بلاک for ساخته شود اما ما این کار را نکرده‌ایم و بنابراین، پایتون این موضوع را به ما گوشزد خواهد کرد.

File "magicians.py", line 3 
  print(magician) 
  ^ 
IndentationError: expected an indented block after 'for' statement on line 2
          

یک نوع دیگر از اشتباهات مربوط به فراموش کردن تورفتگی زمانی رخ می‌دهد که بلاک ما بیش از یک گزاره دارد اما ما فراموش کرده‌ایم که تورفتگی را در ابتدای همه‌ی خطوط بلاک ایجاد کنیم. در این موارد، خطایی توسط پایتون گزارش نمی‌شود اما برنامه خروجی مورد انتظار ما را تولید نمی‌کند. برای مثال، در کد زیر بلاک مربوط به for دو گزاره دارد اما فقط برای یکی از آنها تورفتگی ایجاد شده است.

Copy Icon magicians.py
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
  print(f"{magician.title()}, that was a great trick!")
print(f"I can't wait to see your next trick, {magician.title()}.\n")

نتیجتاً گزاره‌ی دوم به بلاک for تعلق نخواهد داشت و به عنوان یک دستور بعد از حلقه اجرا می‌شود و نتیجه‌ی زیر تولید می‌شود که با نتیجه‌ی مورد انتظار ما یکی نیست.

Alice, that was a great trick! 
David, that was a great trick! 
Carolina, that was a great trick! 
I can't wait to see your next trick, Carolina.
          

در اینجا گزاره‌ی print() دوم تنها یک بار اجرا شده و چون آخرین مقدار مربوط به متغیر magician مقدار Carolina بوده، با خروجی بالا همراه بوده است.

علت اینکه در اینجا خطایی توسط پایتون گزارش نمی‌شود این است که خطایی که رخ داده یک خطای منطقی است. یعنی سینتکس کدها مشکلی ندارند که پایتون آن مشکل را کشف کند، بلکه مشکل به منطق کدها برمی‌گردد و این ما هستیم که باید آن را پیدا کنیم.

ایجاد تورفتگی زائد

خطاهایی که تا اینجا بررسی کردیم، به این دلیل ایجاد می‌شوند که جایی که نیاز به تورفتگی دارد، این کار را نکرده‌ایم. اما خطاهایی هم داریم که به این دلیل ایجاد می‌شوند که جایی که نیاز به تورفتگی ندارد، تورفتگی ایجاد کرده‌ایم. این دست خطاها هم توسط پایتون گزارش می‌شوند.

Copy Icon hello_world.py
message = "Hello Python world!" 
  print(message)

در اینجا به اشتباه در ابتدای گزاره‌ی دوم تورفتگی ایجاد شده و پایتون این موضوع را به اطلاع ما می‌رساند.

File "hello_world.py", line 2
  print(message) 
  ^    
IndentationError: unexpected indent
          

به عنوان یک مثال دیگر که زیاد هم اتفاق می‌افتد، اگر اشتباهاً برای گزاره‌های بعد از حلقه‌ی for (یا هر بلاک دیگر) تورفتگی ایجاد کینم، یا با خطای گرامری و یا با خطای منطقی مواجه می‌شویم. در واثع، با این کار گزاره یا گزاره‌هایی را که به یک بلاک مثل for تعلق ندارند، به آن بلاک منتقل کرده‌ایم. این قبیل اشتباهات گاهی توسط پایتون گزارش شده و گاهی هم منجر به خطای منطقی می‌شوند.

Copy Icon magicians.py
magicians = ['alice', 'david', 'carolina'] 
for magician in magicians: 
  print(f"{magician.title()}, that was a great trick!") 
  print(f"I can't wait to see your next trick, {magician.title()}.\n")  
  print("Thank you everyone, that was a great magic show!")

در اینجا آخرین گزاره‌ی print() مربوط به حلقه نیست اما چون اشتباهاً به آن تورفتگی داده شده، به بلاک for تعلق پیدا می‌کند و نتیجتاً با هر بار تکرار حلقه اجرا می‌شود که یک خطای منطقی است.

Alice, that was a great trick! 
I can't wait to see your next trick, Alice. 
Thank you everyone, that was a great magic show! 
David, that was a great trick! 
I can't wait to see your next trick, David. 
Thank you everyone, that was a great magic show! 
Carolina, that was a great trick! 
I can't wait to see your next trick, Carolina. 
Thank you everyone, that was a great magic show!
          

فراموش کردن کاراکتر دونقطه

کاراکتر دونقطه (colon) در انتهای یک گزاره‌ی for به پایتون اعلام می‌کند که خط بعدی را به عنوان شروع بلاک حلقه در نظر بگیرد. اگر این کاراکتر را فراموش کنیم، با خطای گرامری مواجه می‌شویم.

Copy Icon magicians.py
magicians = ['alice', 'david', 'carolina']
for magician in magicians
  print(magician)

اینجا کاراکتر دونقطه را فراموش کرده‌ایم و بنابراین پایتون خطای زیر را گزارش می‌کند.

File "magicians.py", line 2 
  for magician in magicians 
  ^ 
SyntaxError: expected ':'