Last updated on October 1, 2018
ช่วงนี้ผมมีโอกาสใช้งาน Python และ contribute open source โปรเจกต์หนึ่งอยู่ ปัญหาที่โคตรจะเบสิกของ developer อย่างเราๆ ที่ต้องเจอคือ environment (ต่อไปขอย่อเป็น env ละกัน) บนเครื่องที่ใช้พัฒนากับ env ที่โปรเจกต์ต้องการเป็นคนละ version กัน เราอาจจะติดตั้ง env สำหรับโปรเจกต์นั้นบนเครื่องเราก็ได้แต่ก็จะเกิดปัญหาต่อมา เช่น
- version ของชุดซอฟต์แวร์ที่โปรเจกต์ต้องการกระทบกับ version ของซอฟต์แวร์หลักของระบบ
- version ของชุดซอฟต์แวร์ที่โปรเจกต์ต้องการอาจจะเก่าเกินไปจนติดตั้งบน OS version ปัจจุบันของเราไม่ได้
แม้ว่าเราจะมี Docker ซึ่งสามารถสร้าง container ที่มี env แยกจากระบบหลักได้ แต่บางครั้งก็ไม่สะดวกนักเพราะในระหว่างพัฒนาเราอาจจะต้องใช้ tool chain ต่างๆ ร่วมด้วย เช่น ถ้าผม develop ด้วย Python ก็อาจจะต้องใช้ pip ด้วย เป็นต้น
ภาษา Python เองก็มี virtualenv ซึ่งช่วยให้เราจัดการ env ของ Python โดยสามารถรัน Python version ต่างกันกับแต่ละโปรเจกต์ได้โดยไม่กระทบ version หลักในเครื่อง ส่วนอีกตัวที่จะช่วยให้เราทำงานกับ virtualenv ได้ง่ายขึ้นคือ pyenv
การติดตั้ง pyenv และ virtualenv
อาจจะยุ่งยากนิดนึงเพราะไม่มีใน repo หลัก ส่วนตัวผมเองผมใช้ pyenv ร่วมกับ virtualenvwrapper ก็ติดตั้งตามข้างล่างนี้
sudo apt-get install git python-pip make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev curl sudo pip install virtualenvwrapper git clone https://github.com/pyenv/pyenv.git ~/.pyenv git clone https://github.com/pyenv/pyenv-virtualenvwrapper.git $(pyenv root)/plugins/pyenv-virtualenvwrapper echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc echo 'eval "$(pyenv init -)"' >> ~/.bashrc echo 'pyenv virtualenvwrapper' >> ~/.bashrc exec $SHELL
ในตัวอย่างข้างบนนี้สำหรับคนใช้ bash shell ถ้าใช้ z shell ก็ให้เปลี่ยนจาก ~/.bashrc เป็น ~/.zshrc ครับ
การใช้งาน pyenv
การใช้งานก็ไม่ยุ่งยากมี step ง่ายๆ 2 steps คือ ติดตั้ง Python version ที่ต้องการ, switch ไปใช้ Python ที่เพิ่งติดตั้ง
# ติดตั้ง Python pyenv install 2.7.14 # ตรวจสอบว่ามี version อะไรในเครื่องบ้าง pyenv versions # switch env cd my_project penv local 2.7.17 # ติดตั้ง dependencies ตามปกติ pip install -r requirements.txt
ถ้าต้องการกลับมาใช้ version หลักในเครื่องก็แค่ pyenv local system
สำหรับใครที่กังวลเครื่องการ updaet version pyenv ว่าจะยุ่งยากเพราะเป็นการติดตั้งจาก source ภายนอกก็ไม่ต้องเป็นห่วงเพราะโครงการเตรียม pyenv-update ไว้ให้แล้ว
การแยก environment สำหรับแต่ละโปรเจกต์
สำหรับการใช้งานในโพสต์นี้เมื่อเราติดตั้ง dependencies ต่างๆ แล้วตัว dependencies ต่างๆ จะยังแชร์ใน environment ที่เราใช้อยู่ เช่น หากเรา switch Python 2.7.14 โปรเจกต์ที่ใช้ 2.7.14 ก็จะเห็น module ที่เราติดตั้งด้วยเหมือนกัน ซึ่งก็อาจจะมีปัญหา version ของ module ทำงานร่วมกันไม่ได้อยู่ วิธีที่ดีกว่าคือ dependencies ควรจะใช้ได้เฉพาะโปรเจกต์นั้นโปรเจกต์เดียว แยกขาดจากส่วนอื่นไปเลย ซึ่งสามารถใช้งาน venv ร่วมกับ virtualenv ได้
วิธีติดตั้งใช้งานก็ไม่ยาก แต่มี step เพิ่มนิดหน่อยครับ
cd my_project virtualenv --clear .venv
จะมีโฟลเดอร์ชื่อ .venv จะถูกสร้างขึ้นมาใน my_project ซึ่งถ้าเรา pip install dependencies จะมาลงในนี้แทน แต่การ pip install ต้อง activate venv นี้ก่อนเสมอเพื่อบอกว่าเราจะติดตั้ง dependencies เฉพาะโปรเจกต์นี้เท่านั้น ซึ่งทำได้โดยรันคำสั่งข้างล่างนี้
. .venv/bin/activate && pip install -U -r requirements.txt
จะเห็นว่าต้องใส่ prefix ตอนสั่ง pip install ด้วย ส่วนตัวผมว่ามันไม่สะดวกเอาซะเลย แนะนำให้เขียน script หรือ Makefile แทนดีกว่าครับ