چه چیزهایی در پایتون 3.1 جدید است

نویسنده:

Raymond Hettinger

این مقاله ویژگی‌های جدید پایتون 3.1 را در مقایسه با 3.0 توضیح می‌دهد. پایتون 3.1 در ۲۷ ژوئن ۲۰۰۹ منتشر شد.

PEP 372: دیکشنری‌های مرتب

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

API کلاس OrderedDict اساساً همانند دیکشنری‌های معمولی است، اما کلیدها و مقادیر را به ترتیبی تضمین‌شده پیمایش می‌کند که به زمان نخستین درج هر کلید بستگی دارد. اگر یک ورودی جدید، ورودی موجود را بازنویسی کند، موقعیت درج اصلی بدون تغییر باقی می‌ماند. حذف یک ورودی و درج مجدد آن، آن را به انتها منتقل می‌کند.

کتابخانه استاندارد اکنون استفاده از دیکشنری‌های مرتب را در چندین ماژول پشتیبانی می‌کند. ماژول configparser به‌طور پیش‌فرض از آن‌ها استفاده می‌کند. این امر امکان می‌دهد پرونده‌های پیکربندی خوانده شوند، تغییر داده شوند و سپس به ترتیب اصلی خود بازنوشته شوند. متد _asdict() برای collections.namedtuple() اکنون یک دیکشنری مرتب برمی‌گرداند که مقادیر در آن به همان ترتیب اندیس‌های تاپل زیرین ظاهر می‌شوند. ماژول json با یک object_pairs_hook در حال گسترش است تا امکان ساخت OrderedDict‌ها توسط کدگشا فراهم شود. پشتیبانی از ابزارهای شخص ثالثی مانند PyYAML نیز افزوده شد.

همچنین ملاحظه نمائید

PEP 372 - دیکشنری‌های مرتب

PEP نوشته‌شده توسط آرمین روناکر و ریموند هتینگر. پیاده‌سازی نوشته‌شده توسط ریموند هتینگر.

از آنجا که یک دیکشنری ترتیب‌دار ترتیب درج خود را به یاد می‌آورد، می‌توان از آن در ترکیب با مرتب‌سازی برای ساخت یک دیکشنری مرتب‌شده استفاده کرد:

>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

>>> # dictionary sorted by key
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

>>> # dictionary sorted by value
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

>>> # dictionary sorted by length of the key string
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])

دیکشنری‌های مرتب‌شده‌ی جدید هنگام حذف ورودی‌ها ترتیب مرتب‌سازی خود را حفظ می‌کنند. اما هنگامی که کلیدهای جدید اضافه می‌شوند، کلیدها به انتها افزوده می‌شوند و مرتب‌سازی حفظ نمی‌شود.

PEP 378: مشخص‌کننده قالب برای جداکننده هزارگان

تابع توکار format() و متد str.format() از یک زبان کوچک (mini-language) استفاده می‌کنند که اکنون شامل راهی ساده و مستقل از locale برای قالب‌بندی یک عدد با جداکننده‌ی هزارگان است. این امر راهی برای انسانی‌سازی خروجی یک برنامه فراهم می‌کند و ظاهر حرفه‌ای و خوانایی آن را بهبود می‌بخشد:

>>> format(1234567, ',d')
'1,234,567'
>>> format(1234567.89, ',.2f')
'1,234,567.89'
>>> format(12345.6 + 8901234.12j, ',f')
'12,345.600000+8,901,234.120000j'
>>> format(Decimal('1234567.89'), ',f')
'1,234,567.89'

انواع پشتیبانی‌شده عبارتند از int، float، complex و decimal.Decimal.

بحث‌هایی درباره چگونگی مشخص کردن جداکننده‌های جایگزین مانند نقطه، فاصله، آپاستروف یا زیرخط در جریان است. برنامه‌های آگاه از locale باید از مشخص‌کننده قالب n موجود استفاده کنند که از پیش تا حدی از جداکننده‌های هزارگان پشتیبانی می‌کند.

همچنین ملاحظه نمائید

PEP 378 - مشخص‌کننده قالب برای جداکننده هزارگان

PEP (پیشنهاد بهبود پایتون) نوشته‌شده توسط ری‌موند هتینگر و پیاده‌سازی‌شده توسط اریک اسمیت و مارک دیکینسون.

سایر تغییرات زبان

برخی از تغییرات کوچک‌تر اعمال‌شده در هسته زبان پایتون عبارت‌اند از:

  • پوشه‌ها و آرشیوهای zip که حاوی پرونده‌ی __main__.py هستند، اکنون می‌توانند با ارسال نام آن‌ها به مفسر، مستقیماً اجرا شوند. پوشه/پرونده‌ی zip به‌طور خودکار به‌عنوان نخستین ورودی در sys.path درج می‌شود. (پیشنهاد و وصل اولیه از Andy Chu؛ وصل بازنگری‌شده از Phillip J. Eby و Nick Coghlan؛ bpo-1739468.)

  • نوع int() متد bit_length را به دست آورد که تعداد بیت‌های لازم برای نمایش آرگومان خود به صورت دودویی را برمی‌گرداند:

    >>> n = 37
    >>> bin(37)
    '0b100101'
    >>> n.bit_length()
    6
    >>> n = 2**123-1
    >>> n.bit_length()
    123
    >>> (n+1).bit_length()
    124
    

    (مشارکت‌شده توسط فردریک یوهانسون، ویکتور استینر، ریموند هتینگر و مارک دیکینسون؛ bpo-3439.)

  • فیلدهای رشته‌های format() اکنون می‌توانند به‌طور خودکار شماره‌گذاری شوند:

    >>> 'Sir {} of {}'.format('Gallahad', 'Camelot')
    'Sir Gallahad of Camelot'
    

    در گذشته، این رشته نیازمند فیلدهای شماره‌دار مانند 'Sir {0} of {1}' بود.

    (مشارکت‌شده توسط اریک اسمیت؛ bpo-5237.)

  • تابع string.maketrans() منسوخ شده است و با متدهای ایستای جدید bytes.maketrans() و bytearray.maketrans() جایگزین شده است. این تغییر، سردرگمی درباره‌ی اینکه کدام نوع‌ها توسط ماژول string پشتیبانی می‌شدند را برطرف می‌کند. اکنون، str، bytes و bytearray هر یک متدهای maketrans و translate خود را با جدول‌های ترجمه‌ی میانی از نوع مناسب دارند.

    (با مشارکت Georg Brandl؛ bpo-5675.)

  • سینتکس دستور with اکنون اجازه می‌دهد چندین مدیر زمینه در یک دستور واحد استفاده شوند:

    >>> with open('mylog.txt') as infile, open('a.out', 'w') as outfile:
    ...     for line in infile:
    ...         if '<critical>' in line:
    ...             outfile.write(line)
    

    با سینتکس جدید، تابع contextlib.nested() دیگر مورد نیاز نیست و اکنون منسوخ شده است.

    (مشارکت‌شده توسط Georg Brandl و Mattias Brändström؛ appspot issue 53094.)

  • round(x, n) اکنون اگر x یک عدد صحیح باشد، یک عدد صحیح برمی‌گرداند. پیش از این یک عدد اعشاری برمی‌گرداند:

    >>> round(1123, -2)
    1100
    

    (با مشارکت Mark Dickinson؛ bpo-4707.)

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

    اهمیت این موضوع به‌سادگی با عددی مانند 1.1 دیده می‌شود که معادل دقیقی در ممیز شناور دودویی ندارد. از آنجا که معادل دقیقی وجود ندارد، عبارتی مانند float('1.1') به نزدیک‌ترین مقدار قابل نمایش ارزیابی می‌شود که برابر با 0x1.199999999999ap+0 در مبنای شانزده یا 1.100000000000000088817841970012523233890533447265625 در مبنای ده است. آن نزدیک‌ترین مقدار در محاسبات ممیز شناور بعدی استفاده می‌شد و همچنان نیز استفاده می‌شود.

    آنچه جدید است، نحوه‌ی نمایش داده شدن عدد است. پیش‌تر، پایتون از رویکردی ساده استفاده می‌کرد. مقدار repr(1.1) به‌صورت format(1.1, '.17g') محاسبه می‌شد که به '1.1000000000000001' ارزیابی می‌شد. مزیت استفاده از ۱۷ رقم این بود که به تضمین‌های IEEE-754 تکیه می‌کرد تا اطمینان دهد eval(repr(1.1)) دقیقاً به مقدار اصلی خود رفت‌وبرگشت می‌کند. عیب آن این است که بسیاری از افراد خروجی را گیج‌کننده می‌یافتند (محدودیت‌های ذاتی نمایش دودویی ممیز شناور را اشتباهاً مشکلی در خود پایتون می‌پنداشتند).

    الگوریتم جدید برای repr(1.1) هوشمندتر است و '1.1' را برمی‌گرداند. در عمل، این الگوریتم تمام نمایش‌های رشته‌ای معادل (نمایش‌هایی که با همان مقدار ممیز شناور زیربنایی ذخیره می‌شوند) را جست‌وجو می‌کند و کوتاه‌ترین نمایش را برمی‌گرداند.

    الگوریتم جدید در صورت امکان تمایل دارد نمایش‌های تمیزتری تولید کند، اما مقادیر زیربنایی را تغییر نمی‌دهد. بنابراین همچنان 1.1 + 2.2 != 3.3 برقرار است، حتی اگر نمایش‌ها خلاف آن را القا کنند.

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

    (همکاری اریک اسمیت و مارک دیکنسون؛ bpo-1580)

ماژول‌های جدید، بهبودیافته و منسوخ

  • کلاس collections.Counter برای پشتیبانی از شمارش آسان آیتم‌های یکتا در یک دنباله یا شیء پیمایش‌پذیر اضافه شد:

    >>> Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])
    Counter({'blue': 3, 'red': 2, 'green': 1})
    

    (مشارکت Raymond Hettinger؛ bpo-1696199.)

  • ماژول جدیدی به نام tkinter.ttk برای دسترسی به مجموعه ابزارک‌های تم‌دار Tk اضافه شد. ایده‌ی اصلی ttk این است که کد پیاده‌سازی‌کننده‌ی رفتار یک ابزارک، تا حد امکان، از کد پیاده‌سازی‌کننده‌ی ظاهر آن جدا شود.

    (مشارکت توسط Guilherme Polo؛ bpo-2983.)

  • کلاس‌های gzip.GzipFile و bz2.BZ2File اکنون از پروتکل مدیریت زمینه پشتیبانی می‌کنند:

    >>> # Automatically close file after writing
    >>> with gzip.GzipFile(filename, "wb") as f:
    ...     f.write(b"xxx")
    

    (مشارکت‌شده توسط آنتوان پیترو.)

  • ماژول decimal اکنون از متدهایی برای ایجاد یک شیء ده‌دهی از یک float دودویی پشتیبانی می‌کند. این تبدیل دقیق است، اما گاهی ممکن است تعجب‌آور باشد:

    >>> Decimal.from_float(1.1)
    Decimal('1.100000000000000088817841970012523233890533447265625')
    

    نتیجه‌ی اعشاری طولانی، کسر دودوییِ واقعیِ ذخیره‌شده برای 1.1 را نشان می‌دهد. این کسر رقم‌های زیادی دارد، زیرا 1.1 را نمی‌توان به‌طور دقیق در مبنای دودویی بازنمایی کرد.

    (مشارکت‌شده توسط Raymond Hettinger و Mark Dickinson.)

  • به ماژول itertools دو تابع جدید اضافه شد. تابع itertools.combinations_with_replacement() یکی از چهار تابع برای تولید ترکیبیات از جمله جایگشت‌ها و ضرب‌های دکارتی است. تابع itertools.compress() همانند هم‌نام خود در APL عمل می‌کند. همچنین، تابع از پیش موجود itertools.count() اکنون یک آرگومان اختیاری step دارد و می‌تواند هر نوع دنباله شمارشی از جمله fractions.Fraction و decimal.Decimal را بپذیرد:

    >>> [p+q for p,q in combinations_with_replacement('LOVE', 2)]
    ['LL', 'LO', 'LV', 'LE', 'OO', 'OV', 'OE', 'VV', 'VE', 'EE']
    
    >>> list(compress(data=range(10), selectors=[0,0,1,1,0,1,0,1,0,0]))
    [2, 3, 5, 7]
    
    >>> c = count(start=Fraction(1,2), step=Fraction(1,6))
    >>> [next(c), next(c), next(c), next(c)]
    [Fraction(1, 2), Fraction(2, 3), Fraction(5, 6), Fraction(1, 1)]
    

    (مشارکت‌شده توسط Raymond Hettinger.)

  • collections.namedtuple() اکنون از آرگومان کلیدواژه‌ای rename پشتیبانی می‌کند که اجازه می‌دهد نام‌های فیلد نامعتبر به‌طور خودکار به نام‌های جایگاهی به شکل _0، _1 و غیره تبدیل شوند. این زمانی مفید است که نام فیلدها توسط منبعی خارجی مانند سرآیند CSV، فهرست فیلد SQL یا ورودی کاربر ایجاد می‌شوند:

    >>> query = input()
    SELECT region, dept, count(*) FROM main GROUPBY region, dept
    
    >>> cursor.execute(query)
    >>> query_fields = [desc[0] for desc in cursor.description]
    >>> UserQuery = namedtuple('UserQuery', query_fields, rename=True)
    >>> pprint.pprint([UserQuery(*row) for row in cursor])
    [UserQuery(region='South', dept='Shipping', _2=185),
     UserQuery(region='North', dept='Accounting', _2=37),
     UserQuery(region='West', dept='Sales', _2=419)]
    

    (ارائه‌شده توسط Raymond Hettinger؛ bpo-1818.)

  • توابع re.sub()، re.subn() و re.split() اکنون پارامتر flags را می‌پذیرند.

    (با مشارکت گریگوری اسمیت.)

  • ماژول logging اکنون یک کلاس ساده‌ی logging.NullHandler را برای برنامه‌هایی که خود از گزارش‌گیری استفاده نمی‌کنند اما کد کتابخانه‌ای را فراخوانی می‌کنند که از آن استفاده می‌کند، پیاده‌سازی می‌کند. راه‌اندازی یک هندلر تهی، هشدارهای کاذبی مانند «No handlers could be found for logger foo» را سرکوب می‌کند:

    >>> h = logging.NullHandler()
    >>> logging.getLogger("foo").addHandler(h)
    

    (مشارکت وینای ساجیپ؛ bpo-4384).

  • ماژول runpy که از سوییچ خط فرمان -m پشتیبانی می‌کند، اکنون هنگامی که نام یک بسته ارائه می‌شود، با جست‌وجو و اجرای زیرماژول __main__ از اجرای بسته‌ها پشتیبانی می‌کند.

    (مشارکت از سوی Andi Vajda؛ bpo-4195.)

  • ماژول pdb اکنون می‌تواند به کد منبع بارگذاری‌شده از طریق zipimport (یا هر بارگذار دیگری که با PEP 302 سازگار باشد) دسترسی داشته باشد و آن را نمایش دهد.

    (مشارکت توسط Alexander Belopolsky؛ bpo-4201.)

  • اشیاء functools.partial اکنون می‌توانند پیکل شوند.

(پیشنهادشده توسط Antoine Pitrou و Jesse Noller. پیاده‌سازی‌شده توسط Jack Diederich؛ bpo-5228.)

  • موضوعات راهنمای pydoc را برای نمادها اضافه کنید تا help('@') در محیط تعاملی همان‌طور که انتظار می‌رود کار کند.

    (مشارکت‌شده توسط David Laban؛ bpo-4739.)

  • ماژول unittest اکنون از نادیده گرفتن آزمون‌های منفرد یا کلاس‌های آزمون پشتیبانی می‌کند. همچنین از علامت‌گذاری یک آزمون به عنوان شکست مورد انتظار پشتیبانی می‌کند؛ آزمونی که می‌دانیم معیوب است، اما نباید به عنوان شکست در TestResult شمرده شود:

    class TestGizmo(unittest.TestCase):
    
        @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
        def test_gizmo_on_windows(self):
            ...
    
        @unittest.expectedFailure
        def test_gimzo_without_required_library(self):
            ...
    

    همچنین، آزمون‌های استثناها به‌گونه‌ای ساخته شده‌اند که با استفاده از دستور with با مدیرهای زمینه کار کنند:

    def test_division_by_zero(self):
        with self.assertRaises(ZeroDivisionError):
            x / 0
    

    علاوه بر این، چندین متد ادعای جدید از جمله assertSetEqual()، assertDictEqual()، assertDictContainsSubset()، assertListEqual()، assertTupleEqual()، assertSequenceEqual()، assertRaisesRegexp()، assertIsNone() و assertIsNotNone() افزوده شد.

    (با مشارکت Benjamin Peterson و Antoine Pitrou.)

  • ماژول io سه ثابت جدید برای متد seek() دارد: SEEK_SET، SEEK_CUR و SEEK_END.

  • تاپل sys.version_info اکنون یک تاپل نام‌دار است:

    >>> sys.version_info
    sys.version_info(major=3, minor=1, micro=0, releaselevel='alpha', serial=2)
    

    (با مشارکت Ross Light؛ bpo-4285.)

  • ماژول‌های nntplib و imaplib اکنون از IPv6 پشتیبانی می‌کنند.

    (مشارکت‌شده توسط Derek Morr؛ bpo-1655 و bpo-1664.)

  • ماژول pickle هنگامی که با پروتکل ۲ یا پایین‌تر استفاده شود، برای همکنش‌پذیری بهتر با Python 2.x تطبیق داده شده است. سازمان‌دهی مجدد کتابخانه استاندارد، ارجاع رسمی بسیاری از اشیاء را تغییر داد. برای مثال، __builtin__.set در Python 2، در Python 3 builtins.set نامیده می‌شود. این تغییر تلاش‌ها برای هم‌رسانی داده‌ها بین نسخه‌های مختلف Python را دشوار می‌کرد. اما اکنون وقتی پروتکل ۲ یا پایین‌تر انتخاب شود، پیکل‌ساز به‌طور خودکار از نام‌های قدیمی Python 2 هم برای بارگذاری و هم برای برون‌ریزی استفاده می‌کند. این بازنگاشت به‌صورت پیش‌فرض فعال است، اما می‌توان آن را با گزینه fix_imports غیرفعال کرد:

    >>> s = {1, 2, 3}
    >>> pickle.dumps(s, protocol=0)
    b'c__builtin__\nset\np0\n((lp1\nL1L\naL2L\naL3L\natp2\nRp3\n.'
    >>> pickle.dumps(s, protocol=0, fix_imports=False)
    b'cbuiltins\nset\np0\n((lp1\nL1L\naL2L\naL3L\natp2\nRp3\n.'
    

    عارضه‌ی جانبی تأسف‌انگیز اما ناگزیر این تغییر این است که پیکل‌های پروتکل ۲ تولیدشده توسط Python 3.1 با Python 3.0 قابل خواندن نخواهند بود. جدیدترین پروتکل پیکل، یعنی پروتکل ۳، باید هنگام مهاجرت داده‌ها بین پیاده‌سازی‌های Python 3.x استفاده شود، زیرا تلاشی برای سازگار ماندن با Python 2.x نمی‌کند.

    (مشارکت‌شده توسط Alexandre Vassalotti و Antoine Pitrou، bpo-6137.)

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

    (مشارکت‌شده توسط Brett Cannon.)

بهینه‌سازی‌ها

بهبودهای عمده‌ای در کارایی اضافه شده‌اند:

  • کتابخانه‌ی جدید I/O (همان‌طور که در PEP 3116 تعریف شده است) عمدتاً به زبان پایتون نوشته شده بود و به‌سرعت در پایتون 3.0 به گلوگاهی مشکل‌ساز تبدیل شد. در پایتون 3.1، کتابخانه‌ی I/O به‌طور کامل به زبان C بازنویسی شده است و بسته به وظیفه‌ی موردنظر، ۲ تا ۲۰ برابر سریع‌تر است. نسخه‌ی پایتون خالص همچنان برای اهداف آزمایشی از طریق ماژول _pyio در دسترس است.

    (مشارکت‌شده توسط Amaury Forgeot d'Arc و Antoine Pitrou.)

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

    (مشارکت‌شده توسط Antoine Pitrou، bpo-4688.)

  • با فعال‌سازی گزینه‌ای از configure به نام --with-computed-gotos روی کامپایلرهایی که از آن پشتیبانی می‌کنند (به‌ویژه: gcc، SunPro و icc)، حلقه‌ی ارزیابی بایت‌کد با سازوکار نگاشت جدیدی کامپایل می‌شود که بسته به سیستم، کامپایلر و بنچمارک، افزایش سرعتی تا ۲۰٪ ایجاد می‌کند.

    (مشارکت‌شده توسط Antoine Pitrou به همراه تعدادی از شرکت‌کنندگان دیگر، bpo-4753).

  • کدگشایی UTF-8، UTF-16 و LATIN-1 اکنون دو تا چهار برابر سریع‌تر شده است.

    (مشارکت Antoine Pitrou و Amaury Forgeot d'Arc، bpo-4868.)

  • ماژول json اکنون دارای یک افزونه‌ی C است که کارایی آن را به‌طور چشمگیری بهبود می‌بخشد. علاوه بر این، API به گونه‌ای تغییر داده شد که json فقط با str کار کند، نه با bytes. این تغییر باعث می‌شود ماژول با مشخصات JSON که بر حسب یونیکد تعریف شده است، تطابق نزدیکی داشته باشد.

    (مشارکت‌شده توسط Bob Ippolito و به Py3.1 تبدیل‌شده توسط Antoine Pitrou و Benjamin Peterson؛ bpo-4136.)

  • پیکل‌گشایی اکنون نام‌های ویژگی اشیاء پیکل‌شده را درون‌سازی (intern) می‌کند. این کار در مصرف حافظه صرفه‌جویی می‌کند و به پیکل‌ها اجازه می‌دهد کوچک‌تر باشند.

    (مشارکت Jake McGuire و Antoine Pitrou؛ bpo-5084.)

IDLE

  • منوی Format در IDLE اکنون گزینه‌ای برای حذف فاصله‌های سفید انتهایی از یک پرونده منبع ارائه می‌دهد.

    (مشارکت‌کرده توسط راجر دی. سروی؛ bpo-5150.)

تغییرات ساخت و API زبان C

تغییرات در فرایند ساخت پایتون و در C API شامل موارد زیر است:

  • اعداد صحیح اکنون به‌صورت داخلی یا در مبنای 2**15 یا در مبنای 2**30 ذخیره می‌شوند، که مبنای آن در زمان ساخت تعیین می‌شود. پیش از این، آن‌ها همیشه در مبنای 2**15 ذخیره می‌شدند. استفاده از مبنای 2**30 بهبود عملکرد قابل‌توجهی روی رایانه‌های ۶۴ بیتی به همراه دارد، اما نتایج بنچمارک روی رایانه‌های ۳۲ بیتی متفاوت بوده است. بنابراین، پیش‌فرض، استفاده از مبنای 2**30 روی رایانه‌های ۶۴ بیتی و مبنای 2**15 روی رایانه‌های ۳۲ بیتی است؛ در یونیکس، گزینه‌ی جدید پیکربندی --enable-big-digits وجود دارد که می‌توان از آن برای لغو این پیش‌فرض استفاده کرد.

    به جز بهبودهای کارایی، این تغییر باید برای کاربران نهایی نامرئی باشد، با یک استثنا: برای اهداف آزمون و اشکال‌زدایی، یک sys.int_info جدید وجود دارد که اطلاعاتی درباره‌ی قالب داخلی فراهم می‌کند و تعداد بیت‌ها به ازای هر رقم و اندازه‌ی نوع C استفاده‌شده برای ذخیره‌ی هر رقم را بر حسب بایت مشخص می‌کند:

    >>> import sys
    >>> sys.int_info
    sys.int_info(bits_per_digit=30, sizeof_digit=4)
    

    (مشارکت‌شده توسط Mark Dickinson؛ bpo-4258.)

  • تابع PyLong_AsUnsignedLongLong() اکنون یک pylong منفی را با ایجاد OverflowError به‌جای TypeError مدیریت می‌کند.

    (مشارکت‌شده توسط Mark Dickinson و Lisandro Dalcrin؛ bpo-5175.)

  • PyNumber_Int() منسوخ شده است. به جای آن از PyNumber_Long() استفاده کنید.

    (مشارکت توسط Mark Dickinson؛ bpo-4910.)

  • تابع جدید PyOS_string_to_double() برای جایگزینی توابع منسوخ PyOS_ascii_strtod() و PyOS_ascii_atof() اضافه شد.

    (مشارکت‌شده توسط Mark Dickinson؛ bpo-5914.)

  • PyCapsule به‌عنوان جایگزینی برای API PyCObject افزوده شد. تفاوت اصلی این است که نوع جدید، رابطی کاملاً تعریف‌شده برای انتقال اطلاعات ایمنی نوع و امضایی ساده‌تر برای فراخوانی مخرب دارد. نوع قدیمی API مشکل‌داری داشت و اکنون منسوخ شده است.

    (مشارکت از سوی لری هستینگز؛ bpo-5630.)

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

این بخش تغییرات پیش‌تر توصیف‌شده و سایر رفع اشکال‌هایی را که ممکن است نیازمند تغییراتی در کد شما باشند، فهرست می‌کند:

  • نمایش‌های رشته‌ای جدید اعداد ممیز شناور می‌توانند داک‌تست‌های (doctest) موجود را خراب کنند. برای مثال:

    def e():
        '''Compute the base of natural logarithms.
    
        >>> e()
        2.7182818284590451
    
        '''
        return sum(1/math.factorial(x) for x in reversed(range(30)))
    
    doctest.testmod()
    
    **********************************************************************
    Failed example:
        e()
    Expected:
        2.7182818284590451
    Got:
        2.718281828459045
    **********************************************************************
    
  • بازنگاشت خودکار نام در ماژول pickle برای پروتکل 2 یا پایین‌تر می‌تواند پیکل‌های پایتون 3.1 را در پایتون 3.0 ناخوانا کند. یک راه‌حل استفاده از پروتکل 3 است. راه‌حل دیگر، تنظیم گزینه‌ی fix_imports روی False است. برای جزئیات بیشتر، به بحث بالا مراجعه کنید.