بازآرایی

اغلب شما به جایی می‌رسید که کدتان کار می‌کند امّا101 تشخیص می‌دهید که با شکستن کد به مجموعه‌ای از تابع‌ها با وظیفه‌ی ویژه، می‌توانید آن را بهبود دهید. این فرآیند را بازآرایی می‌نامند. بازآرایی کد شما را تمیز‌تر و خواندن و توسعه‌ی آن را ساده‌تر می‌کند.

ما می‌توانیم remember_me.py را با انتقال منطق آن به یک یا چند تابع بازآرایی کنیم. تمرکز remember_me.py بر تبریک گفتن به کاربر است بنابراین تمام کد موجود را به تابعی به نام greet_user() منتقل می‌کنیم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import json

def greet_user():
    """Greet the user by name."""
    filename = 'username.json'

    try:
        with open(filename) as f:
            username = json.load(f)
    except FileNotFoundError:
        username = input("What is your name? ")
        with open(filename, 'w') as f:
            json.dump(username, f)
        print(f"We'll remember you when you come back, {username}!")
    else:
        print(f"Welcome back, {username}!")

greet_user()

چون الان از یک تابع استفاده می‌کنیم، توضیحات را با یک docstring جایگزین می‌کنیم که توضیح می‌دهد برنامه در حال حاضر چگونه کار می‌کند (۱). این فایل کمی واضح‌تر است امّا تابع greet_user() کارهای دیگری جز سلام کردن به کاربر هم انجام می‌دهد—اگر نام کاربری قبلاً وجود داشته باشد آن را بازیابی می‌کند و اگر نه، برای وارد کردن یک نام کاربری جدید اقدام می‌کند.

بیایید greet_user() را بازآرایی کنیم تا این همه کار مختلف را انجام ندهد. کار را با انتقال کدی که نام کاربری ذخیره‌شده را بازیابی می‌کند شروع می‌کنیم و آن را به یک تابع جدا منتقل می‌کنیم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import json

def get_stored_username():
    """Get stored username if available."""
    filename = 'username.json'

    try:
        with open(filename) as f:
            username = json.load(f)
    except FileNotFoundError:
        return None
    else:
        return username

def greet_user():
    """Greet the user by name."""
    username = get_stored_username()

    if username:
        print(f"Welcome back, {username}!")
    else:
        username = input("What is your name? ")
        filename = 'username.json'
        with open(filename, 'w') as f:
            json.dump(username, f)
        print(f"We'll remember you when you come back, {username}!")

greet_user()

تابعِ جدیدِ get_stored_username() هدف واضحی دارد چنان‌چه در docstring در ۱ هم ذکر شده است. این تابع نام کاربری ذخیره‌شده را بازیابی می‌کند و در صورت پیدا شدن آن را برمی‌گرداند. اگر فایل username.json وجود نداشته باشد این تابع None برمی‌گرداند (۲). این تمرین خوبی است: تابع یا باید مقداری را که شما انتظار دارید یا در غیرِ این صورت None برگرداند. این به ما امکان می‌دهد که خروجی تابع را به سادگی بررسی کنیم. در ۳ اگر بازیابی نام کاربری موفّقیت‌آمیز بود پیامی به کاربر نمایش می‌دهیم و اگر نه، نام کاربری جدید را درخواست می‌کنیم.

باید یک بلوک دیگر کد را از greet_user() بیرون بکشیم. اگر نام کاربری وجود نداشته باشد، باید کدی که تقاضای نام کاربری جدید می‌کند به تابعی مخصوصِ این کار انتقال یابد:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import json

def get_stored_username():
    """Get stored username if available."""
    --snip--

def get_new_username():
    """Prompt for a new username."""
    username = input("What is your name? ")
    filename = 'username.json'
    with open(filename, 'w') as f:
        json.dump(username, f)
    return username

def greet_user():
    """Greet the user by name."""
    username = get_stored_username()
    if username:
        print(f"Welcome back, {username}!")
    else:
        username = get_new_username()
        print(f"We'll remember you when you come back, {username}!")

greet_user()

در این نسخه‌ی نهایی remember_me.py هر تابع یک هدف مشخّص دارد. ما greet_user() را فراخوانی می‌کنیم و آن تابع پیامی مناسب چاپ می‌کند: یا به کاربری را که قبلاً وجود داشته خوش‌آمد می‌گوید یا به کاربر جدید سلام می‌کند. این تابع این کار را با فراخواندن get_stored_username() انجام می‌دهد که تنها مسئول بازیابی نام کاربری (به شرطِ وجود) است. سرانجام greet_user() تابع get_new_username() را در صورت لزوم صدا می‌کند که این تابع آخر فقط مسئول گرفتن نام کاربری جدید و ذخیره کردنِ آن است. بخش بخش کردنِ کار، قسمتِ مهمّی از نوشتن کدی شفّاف است که بتوان آن را به سادگی نگهداری کرد و توسعه داد.