تمام نمونه کدهای این کتاب برای پایتون 3.6 نوشته شده است. به جز تغییرات بسیار جزیی، آنها باید در پایتون 2.7 نیز کار کنند. نویسنده بر این باور است که پایتون 3 از نقطه ی اوج برای انتخاب ترجیحی برای پروژه های جدید جنگو عبور کرده است.
قرار بود توسعه ی پایتون 2.7 در سال 2015 به پایان برسد اما برای 5 سال دیگر تا سال 2020 تمدید شد. پایتون 2.8 وجود نخواهد داشت. همان طور که در فصل 2، طراحی برنامه ذکر شد، بیشتر توزیع های اصلی لینوکس و فروشندگان ابری به طور کامل به استفاده از Python 3 به عنوان پیش فرض یا پشتیبانی از آن روی آورده اند.
این پیوست برای توسعه دهندگانی نوشته شده که با پایتون 3 آشنایی ندارند. پیشینه ی تاریخی مختصر و تغییرات ترکیبی در پایتون 3 مورد بحث قرار گرفته است. به جای ارائه ی پوشش جامع از ویژگی های Python 3، تنها موارد مربوط به توسعه دهندگان جنگو پوشش داده شده است.
پایتون 3 از سر ناچاری متولد شد. یکی از مزاحمت های اصلی پایتون 2، مدیریت ناسازگار آن با کاراکترهای غیرانگلیسی بود (که به طور معمول به عنوان خطای بدنام UnicodeDecode نشان داده می شود). Guido پروژه Python 3 را برای پاکسازی تعدادی از چنین مشکلات زبانی و در عین حال شکستن سازگاری با نسخه های پیشین، آغاز کرد.
اولین نسخه ی آلفا پایتون 3.0 در آگوست 2007 ساخته شد. از آن زمان، پایتون 2 و پایتون 3 چندین سال به طور موازی توسط تیم توسعه ی اصلی توسعه داده شده اند. در نهایت، انتظار می رود پایتون 3 آینده ی این زبان باشد.
این بخش مهم ترین تغییرات پایتون 3 را از دیدگاه توسعه دهندگان جنگو پوشش می دهد. برای درک لیست کامل تغییرات، به بخش خواندن توصیه شده در پایان مراجعه کنید.
مثالها در پایتون 2 و پایتون 3 ارائه شدهاند. بسته به نوع نصب شما، ممکن است لازم باشد همه دستورات پایتون 3 از پایتون به پایتون 3 تغییر کنند.
همه متدهای «unicode» را به «str» تغییر دهید
در پایتون 3، متد «()str» برای نمایش رشتهای مدلهای شما به جای متد «()unicode» با صدای نامناسب فراخوانی میشود. این یکی از واضح ترین راه های شناسایی کدهای پورت شده پایتون 3 است:
python 2
class Person(models.Model):
name = models.TextField()
def __unicode__(self):
return self.name
python 3
class Person(models.Model):
name = models.TextField()
def __str__(self):
return self.name
این نشان دهنده ی تفاوت در نحوه ی برخورد پایتون 3 با رشته ها است. در Python 2، نمایش قابل خواندن توسط انسان یک کلاس را می توان با «()str» (بایت) یا «()unicode» (متن) برگرداند. با این حال، در پایتون 3، نمایش قابل خواندن به سادگی توسط «()str» (متن) برگردانده می شود.
پایتون 2 دارای دو نوع کلاس است: سبک قدیمی (کلاسیک) و سبک جدید. کلاس های سبک جدید کلاس هایی هستند که به طور مستقیم یا غیرمستقیم از شی به ارث می برند. فقط کلاسهای سبک جدید میتوانند از ویژگیهای پیشرفته پایتون مانند اسلاتها، توصیفگرها و ویژگیها استفاده کنند. بسیاری از این ها توسط جنگو استفاده می شود. با این حال، کلاس ها به دلایل سازگاری هنوز به طور پیش فرض قدیمی هستند.
در پایتون 3، کلاسهای قدیمی دیگر وجود ندارند. همانطور که در جدول زیر مشاهده می شود، حتی اگر به صراحت هیچ کلاس والد را ذکر نکنید، کلاس شی به عنوان پایه وجود خواهد داشت. بنابراین، همه کلاس ها به سبک جدید هستند:
python 2
>>> class CoolMixin:
... pass
>>> CoolMixin.__bases__
()
python 3
>>> class CoolMixin:
... pass
>>> CoolMixin.bases
(<class 'object'>,)
فراخوانی ()super آسانتر است
فراخوانی سادهتر ()super، بدون هیچ آرگومان، مقداری از تایپ کردن در پایتون 3 را برای شما ذخیره میکند:
python 2
class CoolMixin(object):
def do_it(self):
return super(CoolMixin, self).do_it()
python 3
class CoolMixin:
def do_it(self):
return super().do_it()
تعیین نام و نمونه کلاس اختیاری است، بنابراین کد شما DRY و کمتر مستعد خطا در هنگام بازآفرینی است.
ساختار دایرکتوری زیر را برای بسته ای به نام app1 تصور کنید:
/app1
/__init__.py
/models.py
/tests.py
اکنون، در پایتون 3، بیایید موارد زیر را در دایرکتوری والد app1 اجرا کنیم:
$ echo "import models" > app1/tests.py
$ python -m app1.tests
Traceback (most recent call last):
... omitted ...
ImportError: No module named 'models'
$ echo "from . import models" > app1/tests.py
$ python -m app1.tests
# Successfully imported
در یک بسته، هنگام مراجعه به یک ماژول خواهر و برادر، بایستی از ورودی های مرتبط صریح استفاده کنید. میتوانید «init.py» را در پایتون 3 حذف کنید، اگرچه معمولاً برای شناسایی یک بسته استفاده میشود.
در پایتون 2، میتوانید از ورود مدلها برای وارد کردن موفقیت آمیز ماژول «models.py» استفاده کنید. با این حال، مبهم است و می تواند به طور تصادفی هر «models.py» دیگری را در مسیر پایتون شما وارد کند. از این رو، این در پایتون 3 ممنوع است و در پایتون 2 نیز ممنوع است.
ما مراقبیم که دادههایی را که از HTTP میآیند یا از آن طریق خارج میشوند، که بر حسب بایت هستند، در مقابل متنهای درون چارچوب، که رشته های بومی (یونیکد) هستند، مخلوط نکنیم.
اساساً برای اشیاء HttpRequest و HttpResponse موارد زیر را در نظر داشته باشید:
- عنوان ها همیشه اشیاء «str» خواهند بود
- جریان های ورودی و خروجی همیشه اشیاء بایتی خواهند بود
برخلاف پایتون 2، رشته ها و بایت ها به طور ضمنی در حین انجام مقایسه یا الحاق با یکدیگر تبدیل نمی شوند. Strings به معنی فقط رشته های یونیکد است.
در پایتون 3، ممکن است لفظ های رشته ای را با پیشوند f ببینید.
این رشته ها ممکن است حاوی عباراتی در داخل براکت های فرفری باشند،
مشابه رشته های قالب پذیرفته شده توسط ()str.format
.
آنها در زمان اجرا با استفاده از پروتکل ()format
ارزیابی خواهند شد.
در اینجا چند نمونه آورده شده است:
>>> class Person:
... def __init__(self, name):
... self.name = name
... def __str__(self):
... return f"name is {self.name}"
...
>>> p = Person("Hexa")
>>> str(p)
'name is Hexa'
اگرچه ممکن است این ترکیب در ابتدا بیگانه به نظر برسد، اما استفاده از آن راحتتر از جایگزینهای قالببندی رشتهای است.
ترکیب و عملکرد مدیریت استثنا در پایتون 3 به طور قابل توجهی بهبود یافته است.
در پایتون 3، شما نمی توانید از نحو جدا شده با کاما برای عبارت except
استفاده کنید.
به جای آن از کلمه کلیدی as
استفاده کنید:
python 2
try:
pass
except e, BaseException:
pass
python 2 and 3
try:
pass
except e as BaseException:
pass
ترکیب جدید برای پایتون 2 نیز توصیه می شود.
در پایتون 3، همه ی استثناها باید (مستقیم یا غیرمستقیم) از BaseException
مشتق شوند.
در عمل، شما استثناهای سفارشی خود را با استخراج از کلاس Exception
ایجاد خواهید کرد.
به عنوان یک پیشرفت عمده در گزارش خطا، اگر یک استثنا در هنگام مدیریت یک استثنا رخ دهد، همه ی زنجیره ی استثناها گزارش می شود:
python 2
>>> try:
... print(undefined)
... except Exception:
... print(oops)
...
Traceback (most recent call
last):
File "<stdin>", line 4, in
<module>
NameError: name 'oops' is not defined
python 3
>>> try:
... print(undefined)
... except Exception:
... print(oops)
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError: name 'undefined' is not defined
During handling of the above exception,
another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
NameError: name 'oops' is not defined
وقتی به این ویژگی عادت کردید، قطعا در پایتون 2 آن را از دست خواهید داد.
توسعه دهندگان اصلی کتابخانه ی استاندارد پایتون را پاکسازی و بهتر سازماندهی کرده اند.
به طور مثال، SimpleHTTPServer
اکنون در ماژول http.server
زندگی می کند:
python 2
$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
python 3
$python -m http.server
Serving HTTP on 0.0.0.0 port 8000 ...
پایتون 3 فقط در مورد اصلاح زبان نیست. همچنین جایی است که توسعه ی پایتون به صورت بینظیر رخ میدهد. این به معنای بهبود زبان از نظر ترکیب، عملکرد و عملکرد داخلی است.
برخی از ماژول های جدید قابل توجه اضافه شده به پایتون 3 به شرح زیر است:
- asyncio: ورودی/خروجی ناهمزمان، حلقه رویداد، برنامهها و وظایف
- اسرار: اعداد تصادفی رمزنگاری قوی
- unittest.mock: کتابخانه شی ساختگی برای آزمایش
- pathlib: مسیرهای سیستم فایل شی گرا
- آمار: توابع آمار ریاضی
حتی اگر برخی از این ماژول ها به وسیله ی پایتون 2 پشتیبانی شوند، مهاجرت به پایتون 3 و استفاده از آنها به عنوان ماژول های داخلی جذاب تر است.
بیشتر توسعه دهندگان جدی پایتون استفاده از محیط های مجازی را
ترجیح می دهند. virtualenv
برای جداسازی تنظیمات پروژه از نصب پایتون
در سراسر سیستم بسیار محبوب است.
خوشبختانه، پایتون 3.3 با یک عملکرد مشابه با استفاده از ماژول venv
یکپارچه شده است.
از پایتون 3.4، یک محیط مجازی جدید با pip
،
یک نصب کننده ی محبوب، از پیش نصب می شود:
$ python -m venv djenv
[djenv] $ source djenv/bin/activate
[djenv] $ pip install django
ما نمیتوانیم تمام تغییرات و بهبودهای Python 3 را در این ضمیمه قرار دهیم. با این حال، سایر تغییرات رایج به شرح زیر است:
- اکنون
()print
یک تابع است: در گذشته یک دستور بود، یعنی آرگومان ها در پرانتز نبودند. - اعداد صحیح سرریز نمی شوند:
sys.maxint
قدیمی است. اعداد صحیح دقت نامحدودی خواهند داشت - نابرابری
operator <>
حذف شده است: به جای آن از != استفاده کنید - تقسیم عدد صحیح واقعی: در پایتون 2، 3/2 به 1 محاسبه می شود. در پایتون 3 به درستی به 1.5 محاسبه می شود.
- از محدوده به جای xrange استفاده کنید:
()range
اکنون تکرارگرها را برمی گرداند، همانطور کهxrange()
در گذشته کار می کرد. - کلیدهای دیکشنری نماها هستند: کلاسهای dict و مانند dict (مانند
QueryDict
) به جای فهرستهایی برای فراخوانیهای متد()keys
و()items
و()values
تکرارگرها را برمیگردانند.
- مطالب جدید در پایتون 3.0 توسط Guido را بخوانید
- برای اطلاع از موارد جدید در هر نسخه از پایتون، موارد جدید در پایتون را در https://docs.python.org/3/whatsnew/ بخوانید.
- For richly-detailed answers about Python 3, read Python 3 Q & A by Nick Coghlan at http://python-notes.curiousefficiency.org/en/latest/python3/questions_and_answers.html
- برای پاسخهای کامل و مفصل درباره ی پایتون 3، پرسش و پاسخ پایتون 3 توسط نیک کوگلان را در آدرس مورد اشاره بخوانید.