مقایسه ویژگی‌های پایتون ۲ و ۳

این مقاله قصد پاسخگویی به سوال یاد شده را ندارد؛ چرا که اساسا پاسخی ندارد و تنها کنایه‌ای است به ظاهر نامطلوب کنونی از جامعه بزرگ پایتون. این مقاله تلاشی است هر چند کوچک، برای شناخت تفاوت بین گذشته و حال پایتون و همچنین بررسی جایگاه امروز نسخه جدید (3x) این زبان برنامه‌‌‌نویسی متن‌باز.
نسخه پایدار 2.0 در شانزدهم اکتبر سال ۲۰۰۰ میلادی و در ادامه نسخه 1.6 منتشر می‌‌‌‌شود؛ توسعه پایتون به همان صورت ادامه می‌‌‌‌یابد تا این که در سوم دسامبر سال ۲۰۰۸ نسخه 3.0 منتشر می‌‌‌‌گردد آن هم تنها دو ماه پس از انتشار نسخه 2.6 پایتون. این نسخه که از آن با نام‌های ‘Py3K ‘ و
‘Python 3000’ نیز یاد می‌‌‌‌شود یک انقلاب در دنیای پایتون ایجاد می‌‌‌‌کند، به شکلی که اعلام می‌‌‌‌شود این نسخه شروع روند جدید زبان پایتون است و با توجه به نوع تغییراتی که داشته دیگر نمی‌‌‌‌تواند از کدهایی که سازگار با نسخه‌های پیشین (2x) نوشته شده‌‌‌اند، پشتیبانی کند. آقای روسوم خیلی پیش از این، نیاز به ایجاد یکسری تغییرات در ساختار و دستور زبان پایتون را احساس کرده بود، شاید نخستین نشانه‌ از لزوم ایجاد تغییرات در پایتون را بتوان از صحبت‌های ایشان در همایش متن‌باز اوریلی (OSCON) سال ۲۰۰۲ با عنوان پشیمانی‌های پایتون (Python Regrets) دریافت کرد. به هر صورت گروه توسعه پایتون در پی رفع این نیاز، از بین حفظ گذشته پایتون و فلسفه سادگی آن دومی را انتخاب می‌‌‌‌کند و ویژگی‌های کهنه کنار گذاشته و ویژگی‌های جدید جایگزین می‌‌‌‌شوند..

ارتقای نسخه با این همه تغییر، آن هم برای یک زبان با ضریب نفوذ بالایی مانند پایتون، کار ساده‌ای نبود و اثرات آن هنوز هم ادامه دارد؛ چرا که زیرساخت شرکت‌های بزرگی به پایتون وابسته بوده و ارتقای نسخه برای آن‌ها حداقل زمانبر خواهدبود.

ارتقای نسخه با این همه تغییر، آن هم برای یک زبان با ضریب نفوذ بالایی مانند پایتون، کار ساده‌ای نبود و اثرات آن هنوز هم ادامه دارد؛ چرا که زیرساخت شرکت‌های بزرگی به پایتون وابسته بوده و ارتقای نسخه برای آن‌ها حداقل زمانبر خواهدبود. برنامه‌ها و کتابخانه‌های کوچک و بزرگ بسیار زیادی توسط کاربران جامعه پایتون برای نیاز‌های ریز و کلان گوناگونی توسعه یافته است که سازگار شدن تمام آن‌ها با نسخه جدید پایتون بعید به نظر می‌‌‌‌رسد و از همه مهم‌تر خود برنامه‌نویسان پایتون هستند که پس از سال‌ها، اکنون مجبور شده‌اند کارهای دیروز خود را با دستور زبان و در مواقعی حتی با کتابخانه و ماژول‌هایی متفاوت به انجام برسانند. با این حساب، برای پر کردن شکاف به وجود آمده بین دیروز و امروز پایتون یا به بیانی هموار کردن مسیر مهاجرت به نسخه جدید پایتون،‌ علاوه بر این که از پیش سعی شده بود تا ویژگی‌های جدید و دستور زبان نسخه 3.0 به نسخه 2.6 تبدیل (Port) شوند، توسعه نسخه قدیمی به اتمام نمی‌‌‌‌رسد و نسخه دیگری با شماره 2.7 در سوم جولای ۲۰۱۰، تقریبا یک سال پس از انتشار نسخه 3.1 به همراه بسیاری از ویژگی‌های جدید آن منتشر می‌‌‌‌شود.
طبق سند PEP 404، هرگز نسخه‌ای با شماره 2.8 به صورت رسمی منتشر نخواهد شد و نسخه 2.7 با یک پشتیبانی درازمدت، نقطه پایان نسخه قدیمی پایتون خواهد بود. ابتدا قرار شد از این نسخه به مدت پنج سال پشتیبانی (تلاش برای رفع باگ‌ها) شود ولی چند ماه پیش، این زمان به 10 سال یعنی تا سال ۲۰۲۰ افزایش یافت.
نسخه جدید پایتون از جنبه‌های زیادی بهبود یافته و نسبت به گذشته تغییرات زیادی کرده است. در ادامه برخی از این تغییرات بررسی خواهد شد. نمونه کدها تنها برای کامل کردن صحبت آورده نشده است و در مواردی بیان‌‌‌کننده برخی ویژگی‌ها نیز به شمار می‌‌‌‌رود.
بارز‌‌‌‌ترین تغییر بر سر فراخوانی print اتفاق افتاده به گونه‌ای که در نسخه جدید از حالت دستور (یک عبارت با دستور زبان خاص) خارج و به صورت یک تابع، با الگوی زیر تعریف شده است:

print(*args, sep=' ', end='\n', file=sys.stdout)

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

>>> # Python 2.7
>>> print >> open('output.txt', 'w'),x ,y 
>>> print x, y,;print x+y
1 2 3
>>> from __future__ import print_function 
>>> print(x, y, end=', sum = ');print(x+y) 
1 2, sum = 3 

>>> # Python 3.4
>>> print(x, y, file=open('output.txt', 'w'), flush=True)
>>> print(x, y, end=' ');print(x+y)

1 2 3
>>> print(x, y, end=', sum = ');print(x+y) 
1 2, sum = 3
>>> print(x, y, sep='...', end='!\n')
1...2!

در نسخه جدید، نوع برخورد پایتون با متن (text) به‌شدت تغییر کرده و به بحث برانگیز‌‌‌‌‌ترین بخش داستان تبدیل شده است. پیش از این، ASCII کد‌‌گذاری پیش‌فرض پایتون بود و از متن توسط یک نوع جامع str ولی محدود به کد‌‌گذاری پیش‌فرض به همراه نوع دیگری با نام unicode (برای رشته‌هایی خارج از محدوده ASCII) پشتیبانی می‌‌‌‌شد. ولی اکنون unicode به کد‌‌گذاری پیش‌فرض پایتون تبدیل و نیز قالب binary از string جدا شده است؛ به گونه‌ای که یک نوع str با کد‌‌گذاری پیش‌فرض که در‌ واقع همان نوع unicode در نسخه پیشین می‌‌‌‌باشد به همراه دو نوع bytes و bytearray برای پوشش قالب binary به وجود آمده است. نوع bytearray، از انواع قابل تغییر (Mutable) پایتون محسوب می‌‌‌‌شود که خود از نوع bytes ایجاد گردیده است؛ این نوع همچنین در نسخه‌های 2.6 و 2.7 تبدیل (Port) شده است.

>>> # Python 2.7
>>> type('Salam Donya!') 
<type 'str'> 
>>> type(b'Salam Donya!') 
<type 'str'> 
>>> type(bytearray(b'Salam Donya!')) 
<type 'bytearray'> 
>>> type(u'Salam Donya\u0021') 
<type 'unicode'> 

>>> # Python 3.4
>>> type('Salam Donya!') 
<class 'str'> 
>>> type(b'Salam Donya!') 
<class 'bytes'> 
>>> type(bytearray(b'Salam Donya!')) 
<class 'bytearray'> 
>>> type(u'Salam Donya\u0021') 
<class 'str'> 
>>> type('Salam Donya\u0021') 
<class 'str'> 
>>> print('Salam Donya\u0021') 
Salam Donya! 

در نسخه قدیمی برای ایجاد نوع set تنها باید از تابع ()set استفاده شود ولی در نسخه جدید علاوه بر این تابع می‌‌‌‌توان به صورت ساده از نماد آکولاد { } نیز استفاده کرد.

>>> # Python 2.7
>>> set() 
set([]) 
>>> set([1, 2, 3, 4]) 
set([1, 2, 3, 4]) 
>>> set([i for i in range(1, 5)]) 
set([1, 2, 3, 4]) 

>>> # Python 3.4
>>> {} 
{} 
>>> {1, 2, 3, 4} 
{1, 2, 3, 4} 
>>> set([1, 2, 3, 4]) 
{1, 2, 3, 4} 
>>> {i for i in range(1, 5)} 
{1, 2, 3, 4} 

توسط نسخه قدیمی حاصل تقسیم (عملگر /) دو عدد صحیح (Integer)، به صورت یک عدد صحیح محاسبه و از مقدار بعد از ممیز (در صورت وجود) صرف نظر می‌‌‌‌شود. ولی توسط نسخه جدید حاصل تقسیم همواره به صورت یک عدد اعشاری
(Floating Point) و با دقتی بیشتر برگردانده می‌‌‌‌شود. رفتار عملگر // (Floor Division) تغییری نداشته است.

>>> # Python 2.7
>>> 10/4 
2 
>>> 10/4.0 
2.5 
>>> from __future__ import division 
>>> 10/4 
2.5 
>>> 10/4.0 
2.5

>>> # Python 3.4
>>> 10/4 
2.5 
>>> 10/4.0 
2.5 

توسط نسخه قدیمی،‌ اعداد صحیح به صورت دو نوع int (با طول محدود) و long (با طول نامحدود) ارائه می‌‌‌‌شود و هرگاه حین محاسبات، سرریزی در شی نوع int رخ بدهد؛ شی به صورت خودکار به نوع long تبدیل می‌‌‌‌شود. ولی در نسخه جدید پایتون، اعداد صحیح توسط همان یک نوع int منتها با طول نامحدود بیان می‌‌‌‌شوند.

>>> # Python 2.7
>>> num = 1393
>>> type(num) 
<type 'int'> 
>>> num = 1393L 
>>> type(num) 
<type 'long'> 

>>> # Python 3.4
>>> num = 1393 
>>> type(num) 
<class 'int'> 
>>> num = 1393L 
SyntaxError: invalid syntax 

عملکرد تابع (xrange) در نسخه جدید، توسط تابع (range) ارائه می‌‌‌‌شود. البته در نسخه پیشین نیز تابعی با همین نام (range) وجود دارد ولی به دلیل این که دنباله تولید شده را به صورت یک نوع داده list ذخیره می‌‌‌‌کند از نظر مصرف حافظه بهینه نبوده و در نسخه جدید حذف شده است.

>>> # Python 2.7
>>> xrange(10) 
xrange(10) 
>>> range(10) 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

>>> # Python 3.4
>>> range(10) 
range(0, 10) 

در نسخه قدیمی، تابع (raw_input) ورودی را از کاربر دریافت و با نوع داده str باز می‌‌‌‌گرداند.
همین عمل در نسخه جدید پایتون توسط تابع (input) انجام می‌‌‌‌پذیرد. البته تابعی با همین نام (input) در کنار raw_input نیز وجود دارد که تنها اعداد را از کاربر دریافت و به صورت نوع داده عددی باز می‌‌‌‌گرد‌‌اند، این تابع در نسخه جدید حذف شده است.

>>> # Python 2.7
>>> num = raw_input('Year: ') 
Year: 1393 
>>> type(num) 
<type 'str'> 
>>> num = input('Year: ') 
Year: 1393 
>>> type(num) 
<type 'int'> 
>>> # Python 3.4
>>> num = input('Year: ') 
Year: 1393 
>>> type(num) 
<class 'str'> 

در نسخه جدید متغیر حلقه for حوزه (Scope) مخصوص به خود را دارد و با متغیرهای حوزه‌های اطراف for تداخل نخواهد داشت.

>>> # Python 2.7
>>> i = 1 
>>> [i for i in range(7)] 
[0, 1, 2, 3, 4, 5, 6] 
>>> i 
6 
>>> # Python 3.4
>>> i = 1 
>>> [i for i in range(7)] 
[0, 1, 2, 3, 4, 5, 6] 
>>> i 
1

در نسخه جدید، خواص (Attributes) تغییر نام داده شده‌اند. به عنوان نمونه: در بحث توابع func_doc به __doc__ و در متد‌ها im_func و im_self به ترتیب به __func__ و __self__ تغییر نام یافته‌اند.

>>> def f:
...   »»»This function is an example.»»» 
...   pass 
>>> # Python 2.7
>>> f.func_name 
'f' 
>>> f.func_doc 
'This function is an example.' 
>>> # Python 3.4
>>> f.__name__ 
'f' 
>>> f.__doc__ 
'This function is an example.' 

در نسخه جدید دو مقدار True و False به عنوان کلمات کلیدی (keyword) تعریف شده است. در نسخه پیشین این طور نیست و کاربر می‌‌‌‌تواند مقدار آن‌ها را دستکاری کند.

>>> # Python 2.7
>>> True = False 
>>> True 
False 
>>> # Python 3.4
>>> True = False 
SyntaxError: can't assign to keyword 

نام تعدادی از ماژول‌ها نیز تغییر کرده است، مانند repr به reprlib یا test.test_support به test.support. همچنین برخی از ماژول‌های مرتبط با یکدیگر بسته‌‌بندی شده و تحت نام یک ماژول در دسترس قرار گرفته‌‌اند، مانند ماژول‌های htmlentitydefs و HTMLParser که تحت ماژول html ارائه شده‌اند. تغییرات ایجاد شده در نسخه 3x پایتون بسیار بیشتر از این موارد بوده و حتی ویژگی‌های جدید زیادی نیز به آن افزوده شده است که برای دریافت اطلاعات کامل‌تر می‌‌‌‌توانید به بخش اسناد وب‌سایت این زبان (http://docs.python.org) مراجعه نمایید.
حیات رسمی نسخه ۲ پایتون رو به پایان است. هر روز تعداد بیش‌‌تری برنامه و کتابخانه با نسخه جدید پایتون سازگار می‌‌‌‌شوند. کتابخانه‌های قدرتمندی همچون Django و PyQt با نسخه جدید خود را سازگار کرده‌اند و امکان استفاده از +GTK توسط PyGObject فراهم شده است. از طرفی، اگر چه هنوز بخش‌های مهمی از جامعه پایتون مانند کتابخانه بزرگ Twisted یا پیاده‌‌‌سازی جاوا زبان پایتون (Jython) با نسخه 3x سازگار نشده‌اند ولی با برنامه‌ریزی توسعه روی نسخه 2.7 پایتون، به سمت نسخه جدید حرکت خواهد کرد. امروزه، بسیاری از توزیع‌های گنو/لینوکس از هر دو نسخه پایتون در بسته‌های خود پشتیبانی می‌‌‌‌کنند و یکی از پرکاربر‌‌‌‌‌ترین آن‌ها، فدورا، طی یک هدف‌‌گذاری تصمیم گرفته است تا رسیدن به انتشار 22، نسخه 3x را به نسخه اصلی پایتون خود تبدیل کند. با گذشت زمان کدها و برنامه‌های بیشتری به سمت پایتون ۳ حرکت می‌‌‌‌کنند و نشست‌‌ها، کتاب‌ها و برگه‌های آموزش زبان پایتون بر حول محور نسخه جدید آن شکل می‌‌‌‌گیرند. متاسفانه با تمام این صحبت‌ها به نظر می‌‌‌‌رسد حداقل یک اثر منفی از ارتقای نسخه جسورانه پایتون همچنان باقی‌مانده و آن بخشی از کاربران قدیمی پایتون هستند که در برابر مهاجرت به نسخه جدید بنا بر دلایلی مقاومت می‌‌‌‌کنند، به هر حال زمان به عقب باز نمی‌‌‌‌گردد و پایتون همچنان زبانی است برای خلق زیبایی.