پایتونیک - معرفی Virtual Environment‌ها قسمت اول

مقدمه

سلام، بهرام هستم. توی این سری از پست‌ها می‌خوام راجعبه چیزهایی صحبت کنم که باعث میشن یک پله کدهای پایتون ما بالاتر بره،‌در حقیقت نکته‌ها و چیز‌های که در طول روز خودم بهشون اهمیت می‌دم،‌ رو می‌خوام به اشتراک بذارم.

قبل از هر چیز می خوام یه چند‌تا اصطلاح که ممکنه خیلی از جاها در طول مجموعه به کار ببرم رو معرفی کنم. این چند‌تا عبارتند از: پایتونیک Pythonic، پایتونیستا Pythonista.

پایتونیک و پایتونیسا در یک نگاه

معمولاً انتظار میره وقتی از یک پایتون دِوِلُپر بپرسید چه چیزی از پایتون رو بیش از هر چیزی بهش علاقه دارید؟ جواب باشه Readability یا خوانایی کد! اما خب این خوانایی کد ریشه در اصولِ کد‌استایل‌های اون داره یا اصولِ پایتونیک کد زدن. در حقیقت وقتی از یک دِوِلُپر حرفه‌ای پایتون (یا Pythonista) می‌شنوید که این بخش از کد پایتونیک نوشته نشده: یعنی از اصولی که باعث می‌شده کد به خواناترین شکل ممکن باشه استفاده نکردید. من در آینده احتمالا بیشتر راجعبه این کد‌استایل‌ها صحبت می‌کنم اما اگر الان علاقه‌مندید که بیشتر بدونید این لینک رو دنبال کنید.

بریم سراغ اصل مطلب

میشه گفت Virtual Environment‌ها یکی از بنیادی ترین Best-practice‌ها توی توسعه نرم‌افزار تحت پایتون هستند. به صورت پیش فرض وقتی شما یک پکیج پایتون رو با پکیج‌منیجر Pip (بخونید پیپ) نصب می‌کنید، این پکیج‌ها توی مسیر‌های پیش فرض نصب میشن. برای اینکه بدونید این مسیر‌های پیش‌فرض کجا هستند، کافیه به ماژول sys که یک ماژول built-in هست(built-in شاید خیلی مرسوم نباشه چون توی داکیومنت‌های خارجی بیشتر کلمه Standard library رو می‌بینیم) بگید این مسیرها کجاست؟

>>> import sys
>>> sys.path
['', '/usr/lib/python36.zip',
'/usr/lib/python3.6',
'/usr/lib/python3.6/lib-dynload',
'/home/bahram/.local/lib/python3.6/site-packages',
'/usr/local/lib/python3.6/dist-packages',
'/usr/lib/python3/dist-packages',
'/usr/lib/python3/dist-packages/IPython/extensions',
'/home/bahram/.ipython']

یعنی چی؟ یعنی وقتی شما یک ماژول رو توی پایتون import می‌کنید، پایتون شروع می‌کنه توی این مسیر‌ها دنبال اون ماژول می‌گرده و اگه اون رو نتونه پیدا کنه خطا بر میگردونه!

چرا من باید به Virtual Environment‌ها اصلا اهمیت بدم؟

جواب اینه بخاطر تمیزکاری. در حقیقت فرض کنید شما دارید روی چندین پروژه کار می‌کنید و هر کدوم از این پروژه‌ها نسخه‌ی مختلفی از یک ماژول رو نیاز دارند. مثلاً یک پروژه‌ی قدیمی جنگو دارید و همزمان یک پروژه‌ی جدید رو استارت زدید. یا مثلاً خیلی از مواقع شما فقط می‌خواید یک ماژول تست کنید،‌ دلیلی نداره این ماژول به صورت مستقیم کل سیستم رو درگیر کنه، بعضی مواقع هم ممکنه به دلایل امنیتی نخواید یک پکیج رو به صورت system-wide نصب کنید یا اصلا ممکنه حق دسترسی لازم رو نداشته باشید!

دقیقاً Virtual Environment‌ها چیکار می‌کنن؟

کاری که virtual environment‌ها می‌کنن اینه که یک کپی کامل از فایل‌های باینری لازم برای اجرا برنامه پایتون و همچنین خود پکیج‌منیجر پیپ میسازه و از این به بعد تمام ماژول ها از مسیر جدید خونده و نوشته میشن.به همین خاطر می‌گن virtual environment یک ابزار مدیریت پیش‌نیازها هست.

برای اینکه بیشتر درکش کنیم بریم سراغ کار عملی! برای ساخت virtual environment ابزار‌های مختلفی وجود داره که معروف‌هاش: virtualenv و virtualenvwrapper هستند. اینکه تفاوت این دوتا چیه،‌ من اینجوری میگم:‌ اگه به صورت تمام وقت پایتون کد میزنید،‌ virtualenvwrapper بهترین گزینه اس برای شما اما اگه در حال یادگیری هستید و هر از چندگاهی با پایتون کدی میزنید توصیه من virtualenv هست و انشاالله بعد از گذشت یک مدت طولانی از کار با virtualenv کوچ کنید به virtualenvwrapper و اون موقع می‌گید ایکاش از روز اول با همین کار می‌کردم :-).
من بخاطر طولانی نشدن این پُست، توی دو قسمت مجزا این دوتارو توضیح میدم.



معرفی آقا virtualenv

خب اول از همه بریم سراغ نصب این دوستمون،‌ نصبش خیلی راحته،‌ کافیه بگیم پیپ virtualenv رو به صورت system-wide برامون نصب کن:

sudo -H pip install virtualenv

خُب، حالا فرض کنیم، یک دایرکتوری داریم به اسم Dream_Project و اونجا داریم روی یک پروژه کار می‌کنیم، داخل دایرکتوری مورد نظر میریم و به virtualenv می‌گیم که از این بعد تمام پکیج‌ها تو این مسیر نصب شن و دیگه کاری با جاهای دیگه نداشته باش:

cd Dream_Project
virtualenv venv

دستور virtualenv یک پارامتر به عنوان ورودی می‌خواد،‌ که در حقیقت یک دایرکتوری با اون اسم می‌سازه و تمام فایل‌های مورد‌نیاز برای اینکه بتونه کارهاشو انجام بده داخل اون میسازه. خیلی مرسومه که این اسم رو معمولا همه‌جا venv می‌ذاریم(شما هم همینکارو بکنید تا جلوتر یه سری Alias واسه راحتی کار بهتون معرفی می‌کنم).

بعد از اینکه دستور virtualenv venv رو اجرا کردید،‌ یک کار دیگه باید بکنید و اون فعال سازی این virtual environment هست. برای اینکار کافیه دستور پایین رو بزنید:

source venv/bin/activate

حالا برای کنجکاوی دستور پایین رو اجرا کنید:

$ which python3
$ which pip3

مسیر عادی python3 هست usr/bin/python3/ ولی الان اگه به خروجی خودتون دقت کنید یک مسیر کاملاً متفاوت به شما میده و اگه پیپ بگید چه پکیج‌های نصب داری؟‌تقریبا باید بگه هیچی:

$ pip3 freeze
pkg-resources==0.0.0

پس، برای هر پروژه ای که دارید کافیه داخل پروژه یکبار به virtualenv بگید کارهای لازمه رو انجام بده و هرباری که داخل دایرکتوری مورد نظر میرید بهش بگید،‌اون رو براتون فعال کنه!

اما چطور غیرفعالش کنم تا بتونم با پایتون system-wide ام کار کنم؟ به راحتی کافیه دستور پایین رو اجرا کنید:

$ deactivate

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

alias ae='deactivate &>/dev/null; source ./venv/bin/activate'
alias de='deactivate &>/dev/null'

اینارو توی bashrc. یا zshrc. تون بذارید تا هربار داخل دایرکتوری پروژه‌تون میرید، تایپ کنید ae و virtualenv براتون فعال و هرموقع خواستید غیرفعال شده بزنید de( این دو تا alias رو من از daniel bader که از خوبای پایتون هست کپی کردم).

لُب مطلب

در نهایت،‌ هر وقت هر پروژه ای رو شروع می‌کنید یا اگر می‌خواهید یک ماژول رو تست کنید فراموش نکنید حتماً از virtualenv استفاده کنید. توی قسمت بعدی می‌خوام virtualenvwrapper رو معرفی کنم و به این نتیجه می‌رسیم که زندگی چقدر با اون راحتتر میشه!

قسمت دوم

از اینجا کجا برم

اگر دنبال این هستید تا بیشتر راجعبه ماژول virtualenv بدونید، این لینک رو دنبال کنید. اگر از این مطلب خوشتون اومده و تونسته به شما کمکی بکنه خیلی خوشحال می‌شم اون رو با دوستاتون به اشتراک بذارید!