تازههای پایتون 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 عادت دارید، به احتمال زیاد شما را دچار دردسر میکنند.
Print یک تابع است¶
دستور print با تابع print() جایگزین شده است که با آرگومانهای کلیدواژهای، بیشتر سینتکس خاص دستور قدیمی print را جایگزین میکند (PEP 3105). مثالها:
Old: print "The answer is", 2*2
New: print("The answer is", 2*2)
Old: print x, # Trailing comma suppresses newline
New: print(x, end=" ") # Appends a space instead of a newline
Old: print # Prints a newline
New: print() # You must call the function!
Old: print >>sys.stderr, "fatal error"
New: print("fatal error", file=sys.stderr)
Old: print (x, y) # prints repr((x, y))
New: print((x, y)) # Not the same as print(x, y)!
شما همچنین میتوانید جداکنندهی بین آیتمها را سفارشی کنید، مثلاً:
print("There are <", 2**32, "> possibilities!", sep="")
که این را تولید میکند:
<4294967296> امکان وجود دارد!
نکته:
تابع
print()از قابلیت فضای نرم (softspace) موجود در دستور قدیمیprintپشتیبانی نمیکند. برای مثال، در پایتون 2.x،print "A\n", "B"رشتهی"A\nB\n"را مینوشت؛ اما در پایتون 3.0،print("A\n", "B")رشتهی"A\n B\n"را مینویسد.در ابتدا، متوجه خواهید شد که در حالت تعاملی،
print xقدیمی را زیاد تایپ میکنید. وقت آن است که انگشتان خود را بازآموزی کنید تا به جای آن،print(x)را تایپ کنید!هنگام استفاده از ابزار تبدیل سورس به سورس
2to3، تمام دستورهایprintبهطور خودکار به فراخوانیهای تابعprint()تبدیل میشوند؛ بنابراین این موضوع برای پروژههای بزرگتر عمدتاً مشکلی محسوب نمیشود.
نماها و پیمایشگرها بهجای فهرستها¶
برخی از 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را بهطور جزئی اعمال کرده بود.)تغییر از
exceptexc, var بهexceptexcasvar. به 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 343: دستور «with». دستور
withاکنون یک قابلیت استاندارد است و دیگر لازم نیست از__future__ایمپورت شود. همچنین نوشتن مدیرهای زمینه و ماژول contextlib را ببینید.PEP 366: ایمپورتهای نسبی صریح از یک ماژول اصلی. این کار سودمندی گزینهی
-mرا زمانی که ماژول ارجاعشده در یک بسته قرار دارد، افزایش میدهد.PEP 3101: قالببندی پیشرفتهی رشته. توجه: توضیحات نسخه 2.6 به متد
format()برای هر دو نوع رشتهی ۸-بیتی و یونیکد اشاره میکند. در نسخه 3.0، تنها نوعstr(رشتههای متنی با پشتیبانی از یونیکد) از این متد پشتیبانی میکند؛ نوعbytesاز آن پشتیبانی نمیکند. برنامه این است که این متد در نهایت تنها API برای قالببندی رشته باشد و منسوخ کردن عملگر%از پایتون 3.1 آغاز شود.PEP 3105: print بهعنوان یک تابع. این اکنون یک ویژگی استاندارد است و دیگر نیازی به ایمپورت کردن آن از
__future__نیست. جزئیات بیشتر در بالا ارائه شده است.PEP 3110: تغییرات در مدیریت استثناها. سینتکس
exceptexcasvar اکنون استاندارد است وexceptexc, var دیگر پشتیبانی نمیشود. (البته، بخشasvar همچنان اختیاری است.)PEP 3112: مقادیر لفظی بایت. نمادگذاری مقدار لفظی رشتهی
b"..."(و گونههای آن مانندb'...'،b"""..."""وbr"...") اکنون یک مقدار لفظی از نوعbytesتولید میکند.PEP 3116: کتابخانه جدید ورودی/خروجی. ماژول
ioاکنون روش استاندارد برای انجام ورودی/خروجی (I/O) پرونده است. تابع توکارopen()اکنون نام مستعری برایio.open()است و آرگومانهای کلیدواژهای اضافی encoding، errors، newline و closefd را دارد. همچنین توجه داشته باشید که آرگومان نامعتبر mode اکنون استثنایValueErrorرا ایجاد میکند، نهIOError. شیء پرونده دودویی زیرین یک شیء پرونده متنی بهصورتf.bufferقابل دسترسی است (اما آگاه باشید که شیء متنی برای سرعت بخشیدن به عملیات کدگذاری و کدگشایی، بافری از خود نگه میدارد).PEP 3118: پروتکل بافر بازنگریشده. تابع توکار قدیمی
buffer()اکنون واقعاً حذف شده است؛ تابع توکار جدیدmemoryview()کارکردی (عمدتاً) مشابه ارائه میدهد.PEP 3119: کلاسهای پایه انتزاعی. ماژول
abcو کلاسهای پایه انتزاعی تعریفشده در ماژولcollectionsاکنون نقش تا حدی برجستهتری در زبان ایفا میکنند و نوعهای مجموعهی توکار مانندdictوlistبه ترتیب مطابق با کلاسهای پایه انتزاعیcollections.MutableMappingوcollections.MutableSequenceهستند.PEP 3127: پشتیبانی و سینتکس مقادیر لفظی عدد صحیح. همانطور که در بالا ذکر شد، نمادگذاری جدید برای مقادیر لفظی هشتایی تنها مورد پشتیبانیشده است و مقادیر لفظی دودویی نیز افزوده شدهاند.
PEP 3141: سلسلهمراتب نوع برای اعداد. ماژول
numbersاستفادهی جدید دیگری از کلاسهای پایه انتزاعی است که «برج عددی» پایتون را تعریف میکند. همچنین به ماژول جدیدfractionsتوجه کنید کهnumbers.Rationalرا پیادهسازی میکند.
تغییرات کتابخانه¶
به دلیل محدودیتهای زمانی، این سند بهطور جامع تغییرات بسیار گستردهی کتابخانهی استاندارد را پوشش نمیدهد. 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: APIjumpahead()حذف شد.ماژول
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. رویهی توصیهشده برای مدیریت همهی استثناها بهجز این دستهی اخیر، استفاده ازexceptExceptionاست.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، بهترین راهبرد به شرح زیر است:
(پیشنیاز:) با پوشش آزمون عالی آغاز کنید.
کد خود را به پایتون 2.6 منتقل کنید. این کار نباید بیش از یک انتقال معمول از پایتون 2.x به پایتون 2.(x+1) زحمت داشته باشد. مطمئن شوید که همهی آزمونهای شما پاس میشوند.
(هنوز از 2.6 استفاده میکنید:) سوئیچ خط فرمان
-3را روشن کنید. این کار هشدارهایی دربارهی ویژگیهایی که در 3.0 حذف خواهند شد (یا تغییر خواهند کرد) را فعال میکند. بدنه آزمونهای خود را دوباره اجرا کنید و کدی را که دربارهی آن هشدار دریافت میکنید اصلاح کنید، تا هیچ هشداری باقی نماند و همهی آزمونهای شما همچنان با موفقیت پاس شوند.مترجم سورسبهسورس
2to3را روی درخت کد منبع خود اجرا کنید. نتیجهی ترجمه را با پایتون 3.0 اجرا کنید. مشکلات باقیمانده را بهصورت دستی برطرف کنید و رفع مشکلات را آنقدر ادامه دهید تا همهی آزمونها دوباره پاس شوند.
توصیه نمیشود که تلاش کنید کد منبعی بنویسید که بدون تغییر روی هر دو پایتون 2.6 و 3.0 اجرا شود؛ در این صورت مجبور خواهید بود از سبک کدنویسی بسیار پیچیده و غیرطبیعی استفاده کنید، برای مثال با پرهیز از دستورهای print، فراکلاسها و بسیاری از موارد دیگر. اگر کتابخانهای را نگهداری میکنید که باید هر دو پایتون 2.6 و پایتون 3.0 را پشتیبانی کند، بهترین رویکرد این است که گام ۳ بالا را به این صورت تغییر دهید که نسخهی 2.6 از کد منبع را ویرایش کرده و مترجم 2to3 را دوباره اجرا کنید، نه اینکه نسخهی 3.0 از کد منبع را ویرایش کنید.
برای انتقال توسعههای C به پایتون 3.0، لطفاً به انتقال ماژولهای توسعه به Python 3 مراجعه کنید.