Python101: น้องงูและถิ่นที่อยู่ 🐍
Tags: python, pipenv, productivity, virtualenv
Published: 2019-12-11 10:09:34

ก่อนอื่นเลย ก็ต้องแนะนำตัวกันก่อน เพราะนี่เป็นบทความแรกของพวกเรา #ppbb👩‍💻
ใช่ บทความนี้ถูกเขียนโดยเราสองคน ซึ่งได้เข้ามาเป็น intern ที่ Pronto tools 💙
จากเวลาครึ่งวันที่พี่ได้สอน python ฉบับเริ่มต้นให้กับพวกเรา ก็ทำให้บทความนี้ถือกำเนิดขึ้นนั่นเอง !

####💙 มาทำความรู้จักกับ Python Interpreter
น้องงูของเราเนี่ยถูกพัฒนาขึ้นมาให้เป็นภาษาที่อ่านง่าย ไม่ซับซ้อน แล้วก็มีข้อยกเว้นน้อยกว่าตัวภาษาอื่น ๆ 

#####: Python have battery includeeee !

ทำไม python ถึงถูกเรียกว่า Battery include ? เป็นเพราะว่า python เป็นภาษาที่สามารถขับเคลื่อนได้ด้วยตัวของมันเอง กล่าวคือ มี library ในตัวเองมากพอที่จะไม่จำเป็นต้อง import มาจากที่อื่น ฉันสามารถอยู่ได้ด้วยตัวเองนะ!

ด้วยตัวภาษาของ python เองที่มี library พื้นฐานมาให้มากพอที่จะใช้งาน ทำให้เราไม่จำเป็นต้องติดตั้ง library อื่นๆ เลย เราจึงสามารถเรียกใช้ python และรันโค้ดของเราได้ง่ายๆเหมือนตัวอย่างนี้เลย

![alt text](https://raw.githubusercontent.com/bimmin/python101/master/py1.png "python101")

😎 ความลับ (ที่ไม่ลับ) ของ python อีกอย่างหนึ่ง: ตัว interpreter ของ python นั้นสามารถเรียกใช้ script หรือ function บน command line ได้เลย

####💙 Pip
คำสั่งที่คนทั่วไปมักจะคุ้นเคยในการลง module ของ python เพียงแค่พิมพ์ pip install … module ทั้งหลายที่ต้องการก็จะโผล่พรึบมาอยู่ในเครื่องอย่างง่ายดาย~

ถามว่า ถ้าเราต้องการ ‘ยืม’ library สำเร็จรูปที่คนอื่นเคยเขียนไว้แล้วมาใช้ได้มั้ย?
  ตอบเลยว่าสำหรับ python นั้น ได้!

เรามีสิ่งที่เรียกว่า PyPi คือเว็บที่ทุกคนสามารถอัพโหลด package/module ของตัวเองให้เป็นสาธารณะและทุกคนสามารถใช้ร่วมกันได้ เหมือนเขียนหนังสือของตัวเองแล้วไปวางไว้ที่ห้องสมุด เจ๋งสุดๆ ไปเลย!

แล้วระบบจัดการตัวเองของ python เนี่ย ถือว่าฉลาดมากๆ เลยนะ มันจะไม่ให้ตัวเองทำงานหนัก ทรัพยากรตัวไหนที่สามารถใช้ซ้ำได้มันก็จะใช้ตัวนั้นแหละ พูดง่ายๆ ก็อย่างเช่น 

โปรเจกต์ monday มีการใช้งาน module drinkbeerwithme🍻 อยู่ แล้วโปรเจกต์ friday มีการใช้งาน module sleeplikecrazy🛌 กับ module drinkbeerwithme🍻, python ก็จะไม่ลง module drinkbeerwithme🍻 ใหม่นะ มันจะไปใช้ module ร่วมกับโปรเจกต์ monday เลย ว้าว!

```
pip freeze and pip list
```

ทั้งสองคำสั่งให้ผลลัพธ์และการแสดงผลคล้ายๆ กัน ต่างกันที่รูปแบบ pip list จะแสดงผล module ทั้งหมดภายในเครื่องในรูปแบบที่เข้าใจง่าย user สามารถดูได้รู้เรื่อง ในขณะที่ pip freeze ก็ใช้ในการแสดงผล module ด้วยเช่นกัน แต่จะอยู่ในรูปแบบของ requirements format แทน

![alt text](https://raw.githubusercontent.com/bimmin/python101/master/py2.png "python101")

```
pip install -r requirement.txt
```

คำสั่งนี้ใช้ในกรณีที่ต้องการลง module หลายๆ ตัวพร้อมกัน โดยสามารถเขียน module และเวอร์ชันที่ต้องการด้วย format เดียวกับ pip freeze ลงในไฟล์ .txt แล้ว install ทีเดียวได้เลย

####💙What is Virtualenv ?
ลองนึกถึงเวลาที่เราต้องทำโปรเจกต์หลาย ๆ โปรเจกต์พร้อมกัน แล้วแต่ละโปรเจกต์ก็มีการเรียกใช้ module ไม่เหมือนกัน หรือดันเป็นคนละ version อีก ทีนี้การจะจัดการกับเจ้าตัว module หรือ library พวกนี้ ให้สามารถใช้งานได้กับทุก ๆ โปรเจกต์ของเราก็ดูจะเป็นเรื่องยาก ถูกมั้ย ? 

เจ้าตัว virtualenv นี่แหละที่จะเข้ามาช่วยในการจัดการกับ environment ของเรา โดยเราสามารถแบ่ง environtment ของเราไว้ให้สำหรับแต่ละโปรเจกต์ใช้อีกที ซึ่งก็จะทำให้การจัดการกับ library ในแต่ละโปรเจกต์ของเราเป็นเรื่องง่ายขึ้นนั่นเอง ! ลองมาดูรูปนี้กัน

![alt text](https://raw.githubusercontent.com/bimmin/python101/master/venv.png "python101venv")

จากรูปเราจะเห็นว่ามี 2 โปรเจกต์ที่มีความต้องการใช้ library ที่แตกต่างกัน เราจึงจำเป็นที่จะต้องใช้ virtualenv ในการจัดการกับ environment ให้กับทั้งสองโปรเจกต์นั่นเอง

สำหรับการติดตั้งก็ไม่จำเป็นต้องทำอะไรเลยค่ะ เพราะใน python3 เนี่ยมีเจ้าตัวนี้ให้เราอยู่แล้ว
ทีนี้เราก็จะมาทำการสร้าง environment ของเรากัน โดยใช้คำสั่ง

```
python -m venv xPronto
```

สิ่งที่เราจะได้ก็คือ มันจะทำการสร้าง folder สำหรับ environment นี้ขึ้นมา โดยใช้ชื่อว่า 
xPronto นั่นเอง

วิธีเรียกใช้ล่ะ? เราต้องทำการ activate มัน โดยใช้คำสั่ง

```
source /path/to/ENV/bin/activate
```

ซึ่งหน้าตาหลังจาก activate ก็จะมีหน้าตาแบบนี้นี่เอง คือจะมี (env) เพื่อบอกเราว่าตอนนี้เราอยู่ใน environment นี้แล้วนะ แล้วเราก็จะสามารถลง library ที่เราต้องการสำหรับโปรเจกต์นี้ได้เลย !

![alt text](https://raw.githubusercontent.com/bimmin/python101/master/py3.png "python101")

ส่วนการจะออกจาก environment เราก็แค่ใช้คำสั่ง

```
deactivate
```

####💙Pyenv
ทีนี้เราจะมาทำความรู้จักกับอีกหนึ่งพระเอกของเราก็คือ Pyenv มันก็คือตัวที่เอามาช่วยในการจัดการกับ python version ของเรา ที่ก็มีออกมาหลาย version ซะเหลือเกิน 

โดยเราก็จะทำการติดตั้งก่อน โดยใช้

```
brew install pyenv
```

และเพื่อให้มั่นใจว่า system จะทำการเรียกใช้ pyenv โดยอัตโนมัติเมื่อเราเปิด terminal เราจะทำการแก้ไขไฟล์ .zshrc (อันนี้ขึ้นอยู่กับ shell ของแต่ละคนเลยค่ะ) โดยเพิ่มคำสั่งข้างล่างนี้ลงไป

```
# PYENV INIT
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(command pyenv init - --no-rehash zsh)"
```

เท่านี้การติดตั้ง pyenv ของเราก็จะเสร็จเรียบร้อย เราจะมาลองเรียกใช้เจ้าตัว pyenv กัน โดยใช้คำสั่ง 

```
pyenv global	
```

ตามชื่อของมันก็บอกเลยว่าเป็น global เพราะฉะนั้น python version ที่ปรากฏก็คือ version ของ system นั่นเอง 

ทีนี้ถ้าเราจะลง python ผ่าน pyenv ก็แค่ใช้คำสั่ง

```
pyenv install version
```

แล้วถ้าเราอยากจะเปลี่ยน version ให้กับ system ของเครื่อง หรือโปรเจกต์ที่ต้องการล่ะ ? pyenv สามารถจัดการได้ง่ายๆเลย โดยใช้คำสั่งดังนี้เลย

```
pyenv global version
#กำหนด python version ให้กับ system ของเรา

pyenv local version
#กำหนด python version ให้กับ project ของเรา
```

มาลองดูตัวอย่างข้างล่างนี้กัน เราจะทำการกำหนด python version ให้กับโปรเจกต์ที่มีชื่อว่า changev เราก็จะเข้าไปที่ folder นั้นก่อน แล้วลองตรวจสอบ version ด้วย pyenv version ก่อน ซึ่งจะเห็นว่าเป็น version 3.8.0 

ทีนี้เราจะกำหนด version ของโปรเจกต์นี้เป็น 3.7.4 แทน จึงใช้คำสั่ง pyenv local 3.7.4 พอลองเรียกใช้ python ดู ก็เป็นอันเสร็จเรียบร้อย !

![alt text](https://raw.githubusercontent.com/bimmin/python101/master/py4.png "python101")

จบไปแล้วกับ python101 ของเรา หลาย ๆ คนก็อาจสงสัยว่าทำไมเราถึงจัดให้มันเป็นส่วนแรกที่จะต้องให้ความสำคัญก่อนการเขียนโค้ด ในกรณีที่เป็นโปรเจกต์เล็ก ๆ อาจจะยังนึกภาพกันไม่ค่อยออก 
แต่ถ้าลองนึกถึงโปรเจกต์ที่ใหญ่ขึ้น มีการทำงานร่วมกับหลายทีม ปัญหาในการจัดการกับ library สำหรับทีมนั้นทีมนี้ อื้อหืออ ไม่อยากจะนึกภาพความยุ่งเหยิงพวกนั้นเลย 

วิธีที่ดีที่สุดคือ วางโครงสร้าง และแบ่ง environment ให้กับแต่ละโปรเจกต์ก่อนเลยค่ะ ทีนี้เราก็สามารถเขียนโค้ดได้อย่างสบายใจ โดยไม่ต้องมากังวลกับการนั่งอัพเดต library ทีหลังเลย! 👩‍💻💙