تازه‌های پایتون 3.0

نویسنده:

Guido van Rossum

این مقاله ویژگی‌های جدید پایتون 3.0 را در مقایسه با نسخه 2.6 توضیح می‌دهد. پایتون 3.0 که با نام «Python 3000» یا «Py3K» نیز شناخته می‌شود، نخستین نسخه پایتون است که عمداً ناسازگار با نسخه‌های قبلی است. پایتون 3.0 در ۳ دسامبر ۲۰۰۸ منتشر شد. تعداد تغییرات نسبت به یک نسخه معمولی بیشتر است و موارد بیشتری از آن‌ها برای همه کاربران پایتون اهمیت دارند. با این حال، پس از هضم این تغییرات، خواهید دید که پایتون واقعاً تغییر چندانی نکرده است -- در مجموع، ما عمدتاً در حال برطرف کردن مزاحمت‌ها و ایرادهای شناخته‌شده و حذف بسیاری از کدهای قدیمی و زائد هستیم.

این مقاله تلاش نمی‌کند مشخصات کامل همه‌ی قابلیت‌های جدید را ارائه دهد، بلکه می‌کوشد مروری کلی و مناسب در اختیار شما بگذارد. برای جزئیات کامل، باید به مستندات پایتون 3.0 و/یا بسیاری از PEP‌ها (پیشنهاد بهبود پایتون) که در متن به آن‌ها ارجاع شده است مراجعه کنید. اگر می‌خواهید پیاده‌سازی کامل و منطق طراحی یک قابلیت خاص را درک کنید، PEP‌ها معمولاً جزئیات بیشتری نسبت به مستندات معمولی دارند؛ اما توجه داشته باشید که PEP‌ها معمولاً پس از پیاده‌سازی کامل یک قابلیت، به‌روز نگه داشته نمی‌شوند.

به دلیل محدودیت‌های زمانی، این سند به اندازه‌ای که باید می‌بود، کامل نیست. همان‌طور که همیشه برای یک انتشار جدید مرسوم است، پرونده‌ی Misc/NEWS در توزیع منبع، انبوهی از اطلاعات دقیق درباره‌ی هر چیز کوچکی که تغییر کرده است را در بر دارد.

موانع رایج

این بخش آن تغییرات معدود را فهرست می‌کند که اگر به پایتون 2.5 عادت دارید، به احتمال زیاد شما را دچار دردسر می‌کنند.

نماها و پیمایش‌گرها به‌جای فهرست‌ها

برخی از APIهای شناخته‌شده دیگر فهرست‌ها را برنمی‌گردانند:

  • متدهای dict یعنی dict.keys()، dict.items() و dict.values() به‌جای فهرست، «نما» برمی‌گردانند. برای مثال، این دیگر کار نمی‌کند: k = d.keys(); k.sort(). به‌جای آن از k = sorted(d) استفاده کنید (این در پایتون 2.5 هم کار می‌کند و به همان اندازه کارآمد است).

  • همچنین، متدهای dict.iterkeys()، dict.iteritems() و dict.itervalues() دیگر پشتیبانی نمی‌شوند.

  • map() و filter() پیمایش‌گر برمی‌گردانند. اگر واقعاً به یک فهرست نیاز دارید و دنباله‌های ورودی همگی طول برابر داشته باشند، یک راه‌حل سریع این است که map() را در list() دربرگیرید، مثلاً list(map(...))، اما راه‌حل بهتر اغلب استفاده از درک فهرستی است (به‌ویژه وقتی کد اصلی از lambda استفاده می‌کند)، یا بازنویسی کد به‌گونه‌ای که اصلاً به فهرست نیاز نداشته باشد. به‌ویژه دشوار حالتی است که map() برای اثرات جانبی تابع فراخوانی می‌شود؛ تبدیل صحیح، استفاده از یک حلقه‌ی معمولی for است (چون ایجاد یک فهرست صرفاً اتلاف خواهد بود).

    اگر دنباله‌های ورودی هم‌طول نباشند، map() با پایان کوتاه‌ترین دنباله متوقف می‌شود. برای سازگاری کامل با map() پایتون 2.x، دنباله‌ها را در itertools.zip_longest() نیز دربرگیرید؛ برای مثال map(func, *sequences) به list(map(func, itertools.zip_longest(*sequences))) تبدیل می‌شود.

  • range() اکنون مانند رفتار پیشینِ xrange() رفتار می‌کند، با این تفاوت که با مقادیر با اندازه‌ی دلخواه کار می‌کند. دومی دیگر وجود ندارد.

  • zip() اکنون یک پیمایش‌گر برمی‌گرداند.

مقایسه‌های ترتیبی

پایتون 3.0 قواعد مقایسه‌های ترتیبی را ساده‌سازی کرده است:

  • عملگرهای مقایسه‌ی ترتیبی (<، <=، >=، >) هنگامی که عملوندها ترتیب طبیعی معناداری نداشته باشند، استثنای TypeError ایجاد می‌کنند. بنابراین، عبارت‌هایی مانند 1 < ''، 0 > None یا len <= len دیگر معتبر نیستند و برای مثال None < None به‌جای بازگرداندن False، استثنای TypeError ایجاد می‌کند. نتیجه‌ی این امر آن است که مرتب‌سازی یک فهرست ناهمگون دیگر معنایی ندارد -- همه‌ی عناصر باید با یکدیگر قابل مقایسه باشند. توجه داشته باشید که این موضوع در مورد عملگرهای == و != صدق نمی‌کند: اشیایی از نوع‌های مختلفِ غیرقابل‌مقایسه همیشه با یکدیگر نابرابر مقایسه می‌شوند.

  • sorted() و list.sort() دیگر آرگومان cmp را که تابعی برای مقایسه فراهم می‌کرد، نمی‌پذیرند. به‌جای آن از آرگومان key استفاده کنید. نکته: آرگومان‌های key و reverse اکنون «صرفاً کلیدواژه‌ای» (keyword-only) هستند.

  • تابع cmp() را باید حذف‌شده در نظر بگیرید و دیگر از متد ویژه‌ی __cmp__() پشتیبانی نمی‌شود. از __lt__() برای مرتب‌سازی، از __eq__() همراه با __hash__() و از سایر مقایسه‌های غنی در صورت نیاز استفاده کنید. (اگر واقعاً به کارکرد cmp() نیاز دارید، می‌توانید از عبارت (a > b) - (a < b) به‌عنوان معادل cmp(a, b) استفاده کنید.)

اعداد صحیح

  • PEP 237: اساساً، long به int تغییر نام یافت. به عبارت دیگر، تنها یک نوع عدد صحیح توکار وجود دارد که int نام دارد؛ اما این نوع عمدتاً مانند نوع قدیمی long رفتار می‌کند.

  • PEP 238: عبارتی مانند 1/2 یک عدد اعشاری برمی‌گرداند. برای دستیابی به رفتار اسلایسی، از 1//2 استفاده کنید. (سینتکس دوم سال‌هاست که وجود دارد، دست‌کم از زمان پایتون 2.2.)

  • ثابت sys.maxint حذف شد، زیرا دیگر محدودیتی برای مقدار اعداد صحیح وجود ندارد. با این حال، می‌توان از sys.maxsize به‌عنوان عدد صحیحی بزرگ‌تر از هر اندیس عملی فهرست یا رشته استفاده کرد. این مقدار با اندازه‌ی «طبیعی» عدد صحیح در پیاده‌سازی مطابقت دارد و معمولاً همان sys.maxint در نسخه‌های قبلی روی همان پلتفرم است (با فرض یکسان بودن گزینه‌های ساخت).

  • repr() یک عدد صحیح بلند دیگر شامل L انتهایی نیست، بنابراین کدی که بدون قید و شرط آن نویسه را حذف می‌کند، به جای آن آخرین رقم را قطع خواهد کرد. (در عوض از str() استفاده کنید.)

  • مقادیر لفظی مبنای هشت دیگر به شکل 0720 نیستند؛ به‌جای آن از 0o720 استفاده کنید.

متن در برابر داده، به‌جای یونیکد در برابر ۸-بیتی

همه چیزهایی که فکر می‌کردید درباره داده‌های دودویی و یونیکد می‌دانید، تغییر کرده است.

  • پایتون 3.0 به جای رشته‌های یونیکد و رشته‌های ۸-بیتی، از مفاهیم متن و داده (دودویی) استفاده می‌کند. همه‌ی متن‌ها یونیکد هستند؛ با این حال، یونیکدِ کدگذاری‌شده به صورت داده‌ی دودویی نمایش داده می‌شود. نوعی که برای نگه‌داری متن استفاده می‌شود str است و نوعی که برای نگه‌داری داده استفاده می‌شود bytes است. بزرگ‌ترین تفاوت با وضعیت 2.x این است که هر تلاشی برای ترکیب متن و داده در پایتون 3.0 باعث ایجاد TypeError می‌شود، در حالی که اگر در پایتون 2.x یونیکد و رشته‌های ۸-بیتی را ترکیب می‌کردید، در صورتی که رشته‌ی ۸-بیتی اتفاقاً فقط شامل بایت‌های ۷-بیتی (اسکی) بود، کار می‌کرد، اما اگر شامل مقادیر غیراسکی بود، UnicodeDecodeError دریافت می‌کردید. این رفتار وابسته به مقدار، طی سال‌ها چهره‌های ناراحت زیادی ایجاد کرده است.

  • در نتیجه‌ی این تغییر در فلسفه، تقریباً تمام کدهایی که از یونیکد، کدگذاری یا داده‌های دودویی استفاده می‌کنند، به احتمال زیاد باید تغییر کنند. این تغییر در جهت بهبود است، زیرا در دنیای 2.x اشکالات فراوانی مربوط به ترکیب متن کدگذاری‌شده و کدگذاری‌نشده وجود داشت. برای آماده بودن در پایتون 2.x، استفاده از unicode را برای تمام متن‌های کدگذاری‌نشده و استفاده از str را فقط برای داده‌های دودویی یا کدگذاری‌شده آغاز کنید. در این صورت، ابزار 2to3 بیشتر کار را برای شما انجام خواهد داد.

  • دیگر نمی‌توانید از مقادیر لفظی u"..." برای متن یونیکد استفاده کنید. با این حال، باید از مقادیر لفظی b"..." برای داده‌های دودویی استفاده کنید.

  • از آنجا که نوع‌های str و bytes را نمی‌توان با هم ترکیب کرد، باید همیشه تبدیل بین آن‌ها را به‌طور صریح انجام دهید. برای رفتن از str به bytes از str.encode() استفاده کنید و برای رفتن از bytes به str از bytes.decode() استفاده کنید. همچنین می‌توانید به ترتیب از bytes(s, encoding=...) و str(b, encoding=...) استفاده کنید.

  • مانند str، نوع bytes تغییرناپذیر است. نوع تغییرپذیر جداگانه‌ای برای نگه‌داشتن داده‌های دودویی بافرشده وجود دارد: bytearray. تقریباً همه‌ی API‌هایی که bytes را می‌پذیرند، bytearray را نیز می‌پذیرند. API تغییرپذیر بر پایه‌ی collections.MutableSequence است.

  • همه‌ی بک‌اسلش‌ها در مقادیر لفظی رشته خام به‌صورت لفظی تفسیر می‌شوند. این بدان معناست که گریزهای '\U' و '\u' در رشته‌های خام به‌طور خاص در نظر گرفته نمی‌شوند. برای مثال، r'\u20ac' در Python 3.0 رشته‌ای از ۶ نویسه است، در حالی که در 2.6، ur'\u20ac' نویسه‌ی منفرد «یورو» بود. (البته، این تغییر فقط بر مقادیر لفظی رشته خام اثر می‌گذارد؛ نویسه‌ی یورو در Python 3.0 برابر '\u20ac' است.)

  • نوع انتزاعی توکار basestring حذف شد. به‌جای آن از str استفاده کنید. انواع str و bytes به‌اندازه‌ی کافی کارکرد مشترک ندارند که وجود یک کلاس پایه‌ی مشترک را توجیه کند. ابزار 2to3 (در ادامه ببینید) تمام موارد basestring را با str جایگزین می‌کند.

  • پرونده‌هایی که به‌صورت پرونده متنی باز می‌شوند (که همچنان حالت پیش‌فرض تابع open() است) همیشه از یک کدگذاری برای نگاشت بین رشته‌ها (در حافظه) و بایت‌ها (روی دیسک) استفاده می‌کنند. پرونده‌های دودویی (که با b در آرگومان حالت باز می‌شوند) همیشه در حافظه از بایت‌ها استفاده می‌کنند. این بدان معناست که اگر پرونده‌ای با حالت یا کدگذاری نادرست باز شود، عملیات I/O به احتمال زیاد آشکارا شکست می‌خورد، به‌جای اینکه بی‌سروصدا داده‌های نادرست تولید کند. همچنین این بدان معناست که حتی کاربران یونیکس هم هنگام باز کردن یک پرونده باید حالت درست (متنی یا دودویی) را مشخص کنند. یک کدگذاری پیش‌فرض وابسته به پلتفرم وجود دارد که در پلتفرم‌های شبه‌یونیکس می‌توان آن را با متغیر محیطی LANG تنظیم کرد (و گاهی نیز با برخی دیگر از متغیرهای محیطی مرتبط با locale که مخصوص پلتفرم هستند). در بسیاری از موارد، اما نه همه، پیش‌فرض سیستم UTF-8 است؛ شما هرگز نباید بر این پیش‌فرض تکیه کنید. هر برنامه‌ای که چیزی بیش از متن اسکی خالص می‌خواند یا می‌نویسد، احتمالاً باید راهی برای نادیده گرفتن کدگذاری داشته باشد. دیگر هیچ نیازی به استفاده از جریان‌های آگاه از کدگذاری در ماژول codecs وجود ندارد.

  • مقادیر اولیه‌ی sys.stdin، sys.stdout و sys.stderr اکنون پرونده‌های متنیِ صرفاً یونیکد هستند (یعنی نمونه‌هایی از io.TextIOBase هستند). برای خواندن و نوشتن داده‌های بایتی با این جریان‌ها، باید از ویژگی io.TextIOBase.buffer آن‌ها استفاده کنید.

  • نام‌های پرونده به‌صورت رشته‌های (یونیکد) به API‌ها ارسال و از آن‌ها بازگردانده می‌شوند. این موضوع می‌تواند مشکلات خاص پلتفرم ایجاد کند، زیرا در برخی پلتفرم‌ها نام‌های پرونده رشته‌های بایتی دلخواه هستند. (از سوی دیگر، در ویندوز نام‌های پرونده به‌طور بومی به‌صورت یونیکد ذخیره می‌شوند.) به‌عنوان یک راهکار، بیشتر API‌هایی که نام پرونده می‌گیرند (مانند open() و بسیاری از توابع ماژول os)، علاوه بر رشته‌ها، اشیاء bytes را نیز می‌پذیرند و تعداد کمی از API‌ها راهی برای درخواست مقدار بازگشتی از نوع bytes دارند. بنابراین، os.listdir() اگر آرگومان آن نمونه‌ای از bytes باشد، فهرستی از نمونه‌های bytes را برمی‌گرداند و os.getcwdb() پوشه‌ی کاری جاری را به‌صورت نمونه‌ای از bytes برمی‌گرداند. توجه داشته باشید که وقتی os.listdir() فهرستی از رشته‌ها را برمی‌گرداند، نام‌های پرونده‌ای که نمی‌توان آن‌ها را به‌درستی کدگشایی کرد، به‌جای ایجاد استثنای UnicodeError حذف می‌شوند.

  • برخی از APIهای سیستمی مانند os.environ و sys.argv نیز می‌توانند هنگامی که بایت‌های فراهم‌شده توسط سیستم با استفاده از کدگذاری پیش‌فرض قابل تفسیر نباشند، مشکل ایجاد کنند. تنظیم متغیر LANG و اجرای مجدد برنامه احتمالاً بهترین روش است.

  • PEP 3138: خروجی repr() یک رشته دیگر نویسه‌های غیراسکی را خنثی نمی‌کند. با این حال، همچنان نویسه‌های کنترلی و نقاط کدی را که در استاندارد یونیکد وضعیت غیرقابل چاپ دارند، خنثی می‌کند.

  • PEP 3120: کدگذاری پیش‌فرض کد منبع اکنون UTF-8 است.

  • PEP 3131: حروف غیراسکی اکنون در شناسه‌ها مجاز هستند. (با این حال، کتابخانه استاندارد به استثنای نام مشارکت‌کنندگان در کامنت‌ها، همچنان فقط اسکی باقی می‌ماند.)

  • ماژول‌های StringIO و cStringIO دیگر وجود ندارند. در عوض، ماژول io را ایمپورت کنید و برای متن و داده به ترتیب از io.StringIO یا io.BytesIO استفاده کنید.

  • همچنین راهنمای عملی یونیکد را ببینید، که برای پایتون 3.0 به‌روزرسانی شده است.

مروری بر تغییرات سینتکس

این بخش مروری کوتاه بر تمام تغییرات نحوی در پایتون 3.0 ارائه می‌دهد.

سینتکس جدید

  • PEP 3107: حاشیه‌نویسی آرگومان و مقدار بازگشتی تابع. این روشی استاندارد برای حاشیه‌نویسی پارامترهای یک تابع و مقدار بازگشتی آن فراهم می‌کند. به چنین حاشیه‌نویسی‌هایی هیچ معناشناسی متصل نیست، به‌جز اینکه می‌توان آن‌ها را در زمان اجرا با استفاده از ویژگی __annotations__ بازرسی کرد. هدف، تشویق به آزمایش از طریق فراکلاس‌ها، دکوراتورها یا چارچوب‌ها است.

  • PEP 3102: آرگومان‌های فقط‌کلیدواژه‌ای. پارامترهای نام‌داری که پس از *args در فهرست پارامترها قرار می‌گیرند، باید در فراخوانی با استفاده از سینتکس کلیدواژه‌ای مشخص شوند. همچنین می‌توانید از یک * تنها در فهرست پارامترها استفاده کنید تا نشان دهید که فهرست آرگومان‌های با طول متغیر را نمی‌پذیرید، اما آرگومان‌های فقط‌کلیدواژه‌ای دارید.

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

  • PEP 3104: دستور nonlocal. اکنون با استفاده از nonlocal x می‌توانید مستقیماً به متغیری در یک محدوده‌ی بیرونی (اما غیرسراسری) انتساب دهید. nonlocal یک واژه‌ی رزرو‌شده‌ی جدید است.

  • PEP 3132: واگشایی گسترش‌یافته‌ی پیمایش‌پذیرها. اکنون می‌توانید چیزهایی مانند a, b, *rest = some_sequence بنویسید. و حتی *rest, a = stuff. شیء rest همیشه یک فهرست (که ممکن است خالی باشد) است؛ سمت راست می‌تواند هر شیء پیمایش‌پذیری باشد. مثال:

    (a, *rest, b) = range(5)
    

    این کار a را برابر 0، b را برابر 4 و rest را برابر [1, 2, 3] قرار می‌دهد.

  • درک دیکشنری: {k: v for k, v in stuff} همان معنی dict(stuff) را دارد، اما انعطاف‌پذیرتر است. (این همان PEP 274 است که حقانیتش اثبات شد. :-)

  • مقادیر لفظی مجموعه، مثلاً {1, 2}. توجه داشته باشید که {} یک دیکشنری خالی است؛ برای مجموعه‌ی خالی از set() استفاده کنید. از درک مجموعه نیز پشتیبانی می‌شود؛ مثلاً {x for x in stuff} همان معنای set(stuff) را دارد، اما انعطاف بیشتری دارد.

  • مقادیر لفظی مبنای هشت جدید، مثلاً 0o720 (از قبل در 2.6 موجود بود). مقادیر لفظی مبنای هشت قدیمی (0720) دیگر وجود ندارند.

  • مقادیر لفظی دودویی جدید، مثلاً 0b1010 (از قبل در 2.6 موجود بود)، و یک تابع توکار متناظر جدید وجود دارد: bin().

  • مقادیر لفظی بایت با یک پیشوند b یا B معرفی می‌شوند و یک تابع توکار جدید متناظر با آن‌ها وجود دارد: bytes().

سینتکس تغییر‌یافته

  • PEP 3109 و PEP 3134: سینتکس جدید دستور raise: raise [expr [from expr]]. در ادامه ببینید.

  • as و with اکنون کلیدواژه‌های رزروشده هستند. (در واقع از نسخه 2.6.)

  • True، False و None واژه‌های رزرو‌شده هستند. (2.6 قبلاً محدودیت‌های مربوط به None را به‌طور جزئی اعمال کرده بود.)

  • تغییر از except exc, var به except exc as var. به PEP 3110 مراجعه کنید.

  • PEP 3115: سینتکس جدید فراکلاس. به جای:

    class C:
        __metaclass__ = M
        ...
    

    اکنون باید استفاده کنید از:

    class C(metaclass=M):
        ...
    

    متغیر سراسریِ ماژول __metaclass__ دیگر پشتیبانی نمی‌شود. (این یک وسیله‌ی کمکی بود تا کلاس‌ها به‌طور پیش‌فرض از نوع سبک جدید (new-style) باشند، بدون آنکه هر کلاس از object مشتق شود.)

  • درک‌های فهرستی دیگر از شکل نحوی [... for var in item1, item2, ...] پشتیبانی نمی‌کنند. به‌جای آن از [... for var in (item1, item2, ...)] استفاده کنید. همچنین توجه داشته باشید که درک‌های فهرستی معناشناسی متفاوتی دارند: آن‌ها بیشتر شبیه قند نحوی برای یک عبارت تولیدگر درون سازنده‌ی list() هستند و به‌طور خاص، متغیرهای کنترل حلقه دیگر به محدوده‌ی اطراف نشت نمی‌کنند.

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

سینتکس حذف‌شده

  • PEP 3113: واگشایی پارامتر تاپل حذف شد. شما دیگر نمی‌توانید def foo(a, (b, c)): ... بنویسید. به جای آن از def foo(a, b_c): b, c = b_c استفاده کنید.

  • بک‌تیک‌ها حذف شدند (به‌جای آن‌ها از repr() استفاده کنید).

  • <> حذف شد (به‌جای آن از != استفاده کنید).

  • کلیدواژه حذف‌شده: exec() دیگر یک کلیدواژه نیست؛ بلکه به‌عنوان یک تابع باقی مانده است. (خوشبختانه سینتکس تابع در 2.x نیز پذیرفته می‌شد.) همچنین توجه داشته باشید که exec() دیگر آرگومان جریان نمی‌پذیرد؛ به‌جای exec(f) می‌توانید از exec(f.read()) استفاده کنید.

  • مقادیر لفظی عدد صحیح دیگر از پسوند l یا L پشتیبانی نمی‌کنند.

  • رشته‌های لفظی دیگر از پیشوند u یا U پشتیبانی نمی‌کنند.

  • سینتکس from ماژول import * تنها در سطح ماژول مجاز است و دیگر درون توابع مجاز نیست.

  • تنها سینتکس قابل قبول برای ایمپورت‌های نسبی، from .[module] import name است. تمام شکل‌های import که با . شروع نمی‌شوند، به‌عنوان ایمپورت‌های مطلق تفسیر می‌شوند. (PEP 328)

  • کلاس‌های کلاسیک حذف شده‌اند.

تغییراتی که از قبل در پایتون 2.6 وجود داشتند

از آنجا که احتمالاً بسیاری از کاربران مستقیماً از پایتون 2.5 به پایتون 3.0 مهاجرت می‌کنند، این بخش ویژگی‌های جدیدی را که در اصل برای پایتون 3.0 طراحی شده بودند اما به پایتون 2.6 بک‌پورت (back-port) شده‌اند، به خواننده یادآوری می‌کند. برای توضیحات طولانی‌تر باید به بخش‌های مربوطه در تازه‌های پایتون 2.6 مراجعه شود.

تغییرات کتابخانه

به دلیل محدودیت‌های زمانی، این سند به‌طور جامع تغییرات بسیار گسترده‌ی کتابخانه‌ی استاندارد را پوشش نمی‌دهد. PEP 3108 مرجع تغییرات عمده‌ی این کتابخانه است. در ادامه مروری فشرده ارائه می‌شود:

  • بسیاری از ماژول‌های قدیمی حذف شدند. برخی، مانند gopherlib (دیگر استفاده نمی‌شود) و md5 (که توسط hashlib جایگزین شد)، پیش‌تر توسط PEP 4 منسوخ شده بودند. برخی دیگر در نتیجه‌ی حذف پشتیبانی از پلتفرم‌های گوناگونی مانند Irix، BeOS و Mac OS 9 حذف شدند (به PEP 11 مراجعه کنید). همچنین برخی ماژول‌ها به دلیل استفاده‌نشدن یا وجود جایگزین بهتر، برای حذف در Python 3.0 انتخاب شدند. برای فهرست جامع به PEP 3108 مراجعه کنید.

  • بسته‌ی bsddb3 حذف شد، زیرا حضور آن در کتابخانه استاندارد اصلی به مرور زمان، به دلیل بی‌ثباتی در آزمون‌ها و زمان‌بندی انتشار Berkeley DB، بار خاصی برای توسعه‌دهندگان اصلی به شمار می‌رفت. با این حال، این بسته زنده و فعال است و به‌صورت بیرونی در https://www.jcea.es/programacion/pybsddb.htm نگهداری می‌شود.

  • برخی ماژول‌ها تغییر نام یافتند، زیرا نام قدیمی آن‌ها PEP 8 را نقض می‌کرد، یا به دلایل مختلف دیگر. فهرست آن‌ها به شرح زیر است:

    نام قدیمی

    نام جدید

    _winreg

    winreg

    ConfigParser

    configparser

    copy_reg

    copyreg

    Queue

    queue

    SocketServer

    socketserver

    markupbase

    _markupbase

    repr

    reprlib

    test.test_support

    test.support

  • یک الگوی رایج در پایتون 2.x این است که یک نسخه از یک ماژول با پایتون خالص پیاده‌سازی شده باشد، به‌همراه یک نسخه شتاب‌دهی‌شده اختیاری که به‌صورت یک توسعه C پیاده‌سازی شده است؛ برای مثال، pickle و cPickle. این کار بار ایمپورت کردن نسخه شتاب‌دهی‌شده و بازگشت به نسخه پایتون خالص را بر دوش هر کاربر این ماژول‌ها می‌گذارد. در پایتون 3.0، نسخه‌های شتاب‌دهی‌شده به‌عنوان جزئیات پیاده‌سازی نسخه‌های پایتون خالص در نظر گرفته می‌شوند. کاربران باید همیشه نسخه استاندارد را ایمپورت کنند؛ این نسخه تلاش می‌کند نسخه شتاب‌دهی‌شده را ایمپورت کند و در صورت عدم موفقیت به نسخه پایتون خالص بازمی‌گردد. جفت pickle / cPickle مشمول این برخورد قرار گرفت. ماژول profile در فهرست نسخه 3.1 قرار دارد. ماژول StringIO به یک کلاس در ماژول io تبدیل شده است.

  • برخی ماژول‌های مرتبط در قالب بسته‌ها گروه‌بندی شده‌اند و معمولاً نام زیرماژول‌ها ساده‌سازی شده است. بسته‌های جدید حاصل عبارت‌اند از:

    • dbm (anydbm, dbhash, dbm, dumbdbm, gdbm, whichdb).

    • html (HTMLParser, htmlentitydefs).

    • http (httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib).

    • tkinter (همه‌ی ماژول‌های مرتبط با Tkinter به‌جز turtle). مخاطبان هدف turtle واقعاً به tkinter اهمیتی نمی‌دهند. همچنین توجه داشته باشید که از پایتون 2.6 به بعد، کارکرد turtle به‌طور چشمگیری بهبود یافته است.

    • urllib (urllib, urllib2, urlparse, robotparse).

    • xmlrpc (xmlrpclib, DocXMLRPCServer, SimpleXMLRPCServer).

برخی تغییرات دیگر در ماژول‌های کتابخانه استاندارد که توسط PEP 3108 پوشش داده نشده‌اند:

  • sets حذف شد. از کلاس توکار set() استفاده کنید.

  • پاک‌سازی ماژول sys: sys.exitfunc()، sys.exc_clear()، sys.exc_type، sys.exc_value و sys.exc_traceback حذف شدند. (توجه داشته باشید که sys.last_type و غیره باقی می‌مانند.)

  • پاک‌سازی نوع array.array: متدهای read() و write() حذف شده‌اند؛ به‌جای آن‌ها از fromfile() و tofile() استفاده کنید. همچنین، کد نوع 'c' برای آرایه حذف شده است — از 'b' برای بایت‌ها یا 'u' برای نویسه‌های یونیکد استفاده کنید.

  • پاک‌سازی ماژول operator: توابع sequenceIncludes() و isCallable() حذف شدند.

  • پاک‌سازی ماژول thread: acquire_lock() و release_lock() حذف شده‌اند؛ به‌جای آن‌ها از acquire() و release() استفاده کنید.

  • پاک‌سازی ماژول random: API jumpahead() حذف شد.

  • ماژول new حذف شده است.

  • توابع os.tmpnam()، os.tempnam() و os.tmpfile() به نفع ماژول tempfile حذف شده‌اند.

  • ماژول tokenize به‌گونه‌ای تغییر یافته است که با بایت‌ها کار کند. نقطه‌ی ورود اصلی اکنون tokenize.tokenize() است، به‌جای generate_tokens.

  • string.letters و مشابه‌هایش (string.lowercase و string.uppercase) دیگر وجود ندارند. به جای آن‌ها از string.ascii_letters و غیره استفاده کنید. (دلیل این حذف آن است که string.letters و مشابه‌هایش رفتاری وابسته به locale داشتند، که برای «ثابت‌های» سراسری با چنین نام‌های جذابی، ایده‌ی بدی است.)

  • نام ماژول __builtin__ به builtins تغییر یافت (با حذف زیرسطرها و افزودن «s»). متغیر __builtins__ که در بیشتر فضاهای نام سراسری یافت می‌شود، بدون تغییر است. برای تغییر یک توکار، باید از builtins استفاده کنید، نه __builtins__!

PEP 3101: رویکردی جدید برای قالب‌بندی رشته

  • سیستم جدیدی برای عملیات قالب‌بندی رشته‌ی توکار جایگزین عملگر % قالب‌بندی رشته می‌شود. (با این حال، عملگر % همچنان پشتیبانی می‌شود؛ در پایتون 3.1 منسوخ خواهد شد و در زمانی بعدی از زبان حذف خواهد شد.) برای اطلاعات کامل، PEP 3101 را بخوانید.

تغییرات در استثناها

APIهای ایجاد و گرفتن استثنا پاکسازی شده‌اند و قابلیت‌های قدرتمند جدیدی افزوده شده‌اند:

  • PEP 352: همه استثناها باید (مستقیم یا غیرمستقیم) از BaseException مشتق شوند. این، ریشه سلسله‌مراتب استثناها است. این به‌عنوان یک توصیه جدید نیست، اما الزام ارث‌بری از BaseException جدید است. (پایتون 2.6 همچنان اجازه می‌داد کلاس‌های کلاسیک پرتاب (raise) شوند، و هیچ محدودیتی روی آنچه می‌توانید بگیرید قرار نمی‌داد.) در نتیجه، استثناهای رشته‌ای سرانجام به‌راستی و به‌کلی مرده‌اند.

  • تقریباً همه‌ی استثناها در واقع باید از Exception مشتق شوند؛ BaseException باید فقط به‌عنوان کلاس پایه برای استثناهایی استفاده شود که باید فقط در بالاترین سطح مدیریت شوند، مانند SystemExit یا KeyboardInterrupt. رویه‌ی توصیه‌شده برای مدیریت همه‌ی استثناها به‌جز این دسته‌ی اخیر، استفاده از except Exception است.

  • StandardError حذف شد.

  • استثناها دیگر مانند دنباله رفتار نمی‌کنند. به‌جای آن از ویژگی args استفاده کنید.

  • PEP 3109: ایجاد استثنا‌ها. اکنون باید از raise Exception(args) به‌جای raise Exception, args استفاده کنید. علاوه بر این، دیگر نمی‌توانید به‌طور صریح یک ردگیری مشخص کنید؛ در عوض، اگر مجبور به انجام این کار هستید، می‌توانید مستقیماً به ویژگی __traceback__ انتساب کنید (در ادامه مراجعه کنید).

  • PEP 3110: گرفتن استثناها. اکنون باید از except SomeException as variable به‌جای except SomeException, variable استفاده کنید. علاوه بر این، متغیر هنگام خروج از بلوک except به‌طور صریح حذف می‌شود.

  • PEP 3134: زنجیره‌سازی استثنا. دو حالت وجود دارد: زنجیره‌سازی ضمنی و زنجیره‌سازی صریح. زنجیره‌سازی ضمنی زمانی رخ می‌دهد که در بلوک هندلر except یا finally استثنایی ایجاد شود. این معمولاً به دلیل وجود اشکال در بلوک هندلر رخ می‌دهد؛ ما این را استثنای ثانویه می‌نامیم. در این حالت، استثنای اصلی (که در حال مدیریت آن بود) به‌عنوان ویژگی __context__ استثنای ثانویه ذخیره می‌شود. زنجیره‌سازی صریح با این سینتکس فراخوانی می‌شود:

    raise SecondaryException() from primary_exception
    

    (که در آن primary_exception هر عبارتی است که یک شیء استثنا تولید می‌کند، احتمالاً استثنایی که پیش‌تر گرفته‌شده است). در این حالت، استثنای اصلی در ویژگی __cause__ استثنای ثانویه ذخیره می‌شود. ردگیری پشته‌ای که هنگام وقوع یک استثنای مدیریت‌نشده چاپ می‌شود، زنجیره‌ی ویژگی‌های __cause__ و __context__ را پیمایش می‌کند و برای هر جزء از زنجیره یک ردگیری پشته‌ی جداگانه چاپ می‌کند که استثنای اصلی در بالای آن قرار دارد. (کاربران جاوا ممکن است این رفتار را تشخیص دهند.)

  • PEP 3134: شیءهای استثنا اکنون ردگیری پشته‌ی خود را به‌عنوان ویژگی __traceback__ ذخیره می‌کنند. این بدان معناست که شیء استثنا اکنون تمام اطلاعات مربوط به یک استثنا را در بر دارد، و دلایل کمتری برای استفاده از sys.exc_info() وجود دارد (هرچند که مورد دوم حذف نشده است).

  • هنگامی که ویندوز در بارگذاری یک ماژول توسعه‌ای شکست می‌خورد، چند پیام استثنا بهبود یافته‌اند. برای مثال، error code 193 اکنون %1 is not a valid Win32 application است. رشته‌ها اکنون با locale‌های غیرانگلیسی سروکار دارند.

سایر تغییرات متفرقه

عملگرها و متدهای ویژه

  • اکنون != مخالفِ == را برمی‌گرداند، مگر اینکه == مقدار NotImplemented را برگرداند.

  • مفهوم «متدهای غیرمقید» (unbound methods) از زبان حذف شده است. هنگام ارجاع به یک متد به‌عنوان ویژگی کلاس، اکنون یک شیء تابع ساده دریافت می‌کنید.

  • __getslice__()، __setslice__() و __delslice__() حذف شدند. سینتکس a[i:j] اکنون به a.__getitem__(slice(i, j)) تبدیل می‌شود (یا __setitem__() یا __delitem__()، وقتی به‌ترتیب به‌عنوان هدف انتساب یا هدف حذف استفاده شود).

  • PEP 3114: متد استاندارد next() به __next__() تغییر نام یافته است.

  • متدهای ویژه‌ی __oct__() و __hex__() حذف شده‌اند -- oct() و hex() اکنون برای تبدیل آرگومان به عدد صحیح از __index__() استفاده می‌کنند.

  • پشتیبانی از __members__ و __methods__ حذف شد.

  • ویژگی‌های تابع با نام func_X برای استفاده از شکل __X__ تغییر نام داده شده‌اند و بدین ترتیب این نام‌ها در فضای نام ویژگی‌های تابع برای ویژگی‌های تعریف‌شده توسط کاربر آزاد می‌شوند. به‌طور مشخص، func_closure، func_code، func_defaults، func_dict، func_doc، func_globals و func_name به ترتیب به __closure__، __code__، __defaults__، __dict__، __doc__، __globals__ و __name__ تغییر نام داده شدند.

  • __nonzero__() اکنون __bool__() است.

توکارها

  • PEP 3135: super() جدید. اکنون می‌توانید super() را بدون آرگومان فراخوانی کنید و (با فرض اینکه این در یک متد نمونه‌ی معمولی تعریف‌شده درون دستور class باشد) کلاس و نمونه‌ی درست به‌طور خودکار انتخاب خواهند شد. با آرگومان‌ها، رفتار super() بدون تغییر است.

  • PEP 3111: raw_input() به input() تغییر نام یافت. یعنی، تابع جدید input() یک سطر را از sys.stdin می‌خواند و آن را با حذف سطر جدید انتهایی برمی‌گرداند. اگر ورودی پیش از موعد خاتمه یابد، EOFError مطرح می‌شود. برای به‌دست آوردن رفتار قدیمی input()، از eval(input()) استفاده کنید.

  • تابع توکار جدید next() برای فراخوانی متد __next__() بر روی یک شیء اضافه شد.

  • راهبرد گرد کردن و نوع بازگشتی تابع round() تغییر کرده‌اند. حالت‌های دقیقاً میانی اکنون به نزدیک‌ترین نتیجه‌ی زوج گرد می‌شوند، نه به سمت دور از صفر. (برای مثال، round(2.5) اکنون 2 را برمی‌گرداند، نه 3.) round(x[, n]) اکنون به جای اینکه همیشه یک عدد اعشاری برگرداند، کار را به x.__round__([n]) واگذار می‌کند. این تابع به‌طور کلی هنگام فراخوانی با یک آرگومان، یک عدد صحیح و هنگام فراخوانی با دو آرگومان، مقداری از همان نوع x برمی‌گرداند.

  • intern() به sys.intern() منتقل شد.

  • حذف‌شده: apply(). به جای apply(f, args) از f(*args) استفاده کنید.

  • تابع callable() حذف شد. به جای callable(f) می‌توانید از isinstance(f, collections.Callable) استفاده کنید. تابع operator.isCallable() نیز حذف شده است.

  • تابع coerce() حذف شد. این تابع اکنون که کلاس‌های کلاسیک از بین رفته‌اند، دیگر کاربردی ندارد.

  • execfile() حذف شد. به جای execfile(fn) از exec(open(fn).read()) استفاده کنید.

  • نوع file حذف شد. از open() استفاده کنید. اکنون چندین نوع مختلف از جریان‌ها وجود دارد که open می‌تواند در ماژول io برگرداند.

  • reduce() حذف شد. اگر واقعاً به آن نیاز دارید، از functools.reduce() استفاده کنید؛ با این حال، در ۹۹ درصد موارد یک حلقه‌ی صریح for خواناتر است.

  • reload() حذف شد. از imp.reload() استفاده کنید.

  • حذف شد. dict.has_key() -- به جای آن از عملگر in استفاده کنید.

تغییرات ساخت و C API

به دلیل محدودیت‌های زمانی، در اینجا فهرست بسیار ناقصی از تغییرات C API ارائه شده است.

  • پشتیبانی از چندین سکو حذف شد، از جمله اما نه محدود به Mac OS 9، BeOS، RISCOS، Irix و Tru64.

  • PEP 3118: API جدید بافر.

  • PEP 3121: راه‌اندازی و نهایی‌سازی ماژول توسعه‌ای.

  • PEP 3123: سازگار کردن PyObject_HEAD با C استاندارد.

  • پشتیبانی C API برای اجرای محدود (restricted execution) دیگر وجود ندارد.

  • PyNumber_Coerce()، PyNumber_CoerceEx()، PyMember_Get() و PyMember_Set() API‌های C حذف شده‌اند.

  • C API جدید PyImport_ImportModuleNoBlock()، مانند PyImport_ImportModule() کار می‌کند، اما روی قفل ایمپورت مسدود نمی‌شود (به جای آن خطا برمی‌گرداند).

  • نام جایگاه و متد تبدیل بولی در سطح C تغییر کرد: nb_nonzero اکنون nb_bool است.

  • METH_OLDARGS و WITH_CYCLE_GC از C API حذف شدند.

کارایی

نتیجه‌ی نهایی تعمیم‌های 3.0 این است که پایتون 3.0 بنچمارک pystone را حدود ۱۰ درصد کندتر از پایتون 2.5 اجرا می‌کند. به احتمال زیاد بزرگ‌ترین علت، حذف رسیدگی ویژه به اعداد صحیح کوچک است. جای بهبود وجود دارد، اما این کار پس از انتشار 3.0 انجام خواهد شد!

انتقال به پایتون 3.0

برای انتقال کد منبع موجود پایتون 2.5 یا 2.6 به پایتون 3.0، بهترین راهبرد به شرح زیر است:

  1. (پیش‌نیاز:) با پوشش آزمون عالی آغاز کنید.

  2. کد خود را به پایتون 2.6 منتقل کنید. این کار نباید بیش از یک انتقال معمول از پایتون 2.x به پایتون 2.(x+1) زحمت داشته باشد. مطمئن شوید که همه‌ی آزمون‌های شما پاس می‌شوند.

  3. (هنوز از 2.6 استفاده می‌کنید:) سوئیچ خط فرمان -3 را روشن کنید. این کار هشدارهایی درباره‌ی ویژگی‌هایی که در 3.0 حذف خواهند شد (یا تغییر خواهند کرد) را فعال می‌کند. بدنه آزمون‌های خود را دوباره اجرا کنید و کدی را که درباره‌ی آن هشدار دریافت می‌کنید اصلاح کنید، تا هیچ هشداری باقی نماند و همه‌ی آزمون‌های شما همچنان با موفقیت پاس شوند.

  4. مترجم سورس‌به‌سورس 2to3 را روی درخت کد منبع خود اجرا کنید. نتیجه‌ی ترجمه را با پایتون 3.0 اجرا کنید. مشکلات باقی‌مانده را به‌صورت دستی برطرف کنید و رفع مشکلات را آن‌قدر ادامه دهید تا همه‌ی آزمون‌ها دوباره پاس شوند.

توصیه نمی‌شود که تلاش کنید کد منبعی بنویسید که بدون تغییر روی هر دو پایتون 2.6 و 3.0 اجرا شود؛ در این صورت مجبور خواهید بود از سبک کدنویسی بسیار پیچیده و غیرطبیعی استفاده کنید، برای مثال با پرهیز از دستورهای print، فراکلاس‌ها و بسیاری از موارد دیگر. اگر کتابخانه‌ای را نگهداری می‌کنید که باید هر دو پایتون 2.6 و پایتون 3.0 را پشتیبانی کند، بهترین رویکرد این است که گام ۳ بالا را به این صورت تغییر دهید که نسخه‌ی 2.6 از کد منبع را ویرایش کرده و مترجم 2to3 را دوباره اجرا کنید، نه اینکه نسخه‌ی 3.0 از کد منبع را ویرایش کنید.

برای انتقال توسعه‌های C به پایتون 3.0، لطفاً به انتقال ماژول‌های توسعه به Python 3 مراجعه کنید.