Python Modules - วิธีการสร้าง#

10 minutes

วัตถุประสงค์

หลังจากทำทำแล็บ นศ.จะสามารถ

  • เขียนโมดูลและใช้โมดูลที่สร้างขึ้นเองได้

  • ใช้ (Line & Cell) Magic Commands ใน IPython ได้

Ref:


โดยทั่วไป การเขียนโปรแกรมที่มีการนำไปใช้ประโยชน์ได้อย่างจริงจัง โปรแกรมจะมีขนาดใหญ่ ดังนั้นจึงมีความจำเป็นต้องแยกโปรแกรมออกเป็นส่วนๆ (หลายๆ ไฟล์) เพื่อให้ง่ายต่อการจัดการและแก้ไขโปรแกรม จนถึงการพัฒนาต่อยอดโปรแกรม

Python เรียกแต่ละส่วนที่แยกออกมาว่า โมดูล (module) มีนามสกุลไฟล์ (Extension) เป็น .py

ไฟล์โมดูล#

ไฟล์โน๊ตบุ๊ค (Extension .ipynb (IPython Notebook); IPython kenel: Jupyter Notebook, IPython Notebook) ที่เราเขียนที่ผ่านๆ มา เก็บทั้งไพธอนซอสโค๊ด (Soure code) ใน Code cell ข้อความเอกสาร (Markdown-formatted document/text) ใน Markdown cell และผลลัพธ์ของการรันใน Output cell ไว้ในไฟล์เดียว แต่สำหรับไฟล์ดโมดูล (Extension .py)เป็นไฟล์ที่มีเฉพาะไพธอนซอสโค๊ดเท่านั้น

ดังนั้น การใช้โน๊ตบุ๊กเขียนโมดูลต้องเขียนเฉพาะไพธอนซอสโค๊ด (Code cell) เท่านั้น

วิธีการเปลี่ยนไฟล์โน๊ตบุ๊คเป็นไฟล์โมดูล#

หลังจากที่เราเขียนไพธอนซอสโค๊ดในไฟล์โน๊ตบุ๊คแล้ว เราก็ต้องเปลี่ยนไฟล์โน๊ตบุ๊ค (.ipynb) ให้เป็นไฟล์โมดูล (.py) โดยการ…

  • หากเขียนด้วย Jupyter notebook ให้กดตรงแถบเมนู “File” เลือก “Download as” แล้วคลิก “Python (.py)” ตั้งชื่อไฟล์ที่ต้องการเซฟ

  • หากเขียนด้วย Jupyter lab ให้กดตรงแถบเมนู “File” เลือก “Export Notebook as” แล้วคลิก “Notebook to Executable Script” ตั้งชื่อไฟล์ที่ต้องการเซฟ

ก็จะได้ไฟล์ที่มีเฉพาะซอสโค๊ด (ส่วนอื่นๆ ที่ไม่ใช่ซอสโค๊ดจะกลายเป็น Comment) มีเป็นนามสกุลเป็น .py

โดยปรกติไฟล์ทั้งหมด ทั้งไฟล์โปรแกรมหลักและไฟล์โมดูลต่างๆ จะถูกเก็บไว้ที่ Directory (Folder) เดียวกัน เราสามารถใช้ Line magic command %pwd ตรวจสอบ Directory (Folder) ที่กำลังใช้งานอยู่ได้

%pwd
'/Users/tube.sc/Data_KMITL/Courses_onMac/2021_Python/PyHTML_v02(No_HW)_4std'

Note: Magic Commands
%pwd เป็นคำสั่งที่ใช้เฉพาะในกรณีที่รันภายใต้ IPython (Interactive Python) เช่น Jupyter notebook, JupyterLab, Google Colaboratory (Colab) เท่านั้น เมื่อรันคำสั่งนี้ จะแสดงผลลัพธ์ในเซลล์เอาต์พุตและบันทึกเก็บในโน้ตบุ๊กได้

Magic Commands อื่นๆ เช่น %system date โดยสามารถพิมพ์คำสั่ง %lsmagic ลงใน Code cell เพื่อแสดงลิสต์ของ Magic Command ทั้งหมดได้ (ดูรายละเอียดในลิงค์ข้างบน)

ในการเซฟไฟล์ให้เป็น .py นอกเหนือจากวิธีปรกติข้างต้นแล้ว ยังอีกวิธีที่สามารถทำได้เช่นกัน

นั่นคือ ใช้คำสั่ง Cell magic command %%file <file_name.py>

เช่น ในกรณีที่เราได้เขียนโค้ดฟังก์ชัน fact() (ฟังก์ชันคำนวณค่าแฟกทอเรียล (Factorial) \(n!\) ) ขึ้นมา แล้วต้องการเซฟเฉพาะ Cell ดังกล่าวให้อยู่ในรูปของไฟล์ โดยมีชื่อว่า factorial.py ก็สามารถทำได้โดยใช้คำสั่ง %%file factorial.py ดังตัวอย่างต่อไปนี้

Note: คำสั่ง Cell Magic Command ต้องอยู่บรรทัดแรกสุดของ cell เสมอ
%%file factorial.py

# คืนค่ากลับเป็นค่าแฟคทอเรียล n! 
def fact(n):
    prod = 1
    for i in range(1, n + 1):
        prod *= i
    return prod
Overwriting factorial.py

*** Note: ***

“ตรงโค้ดตั้งแต่ cell magic command %%file factorial.py ผมลองรันแล้วมัน PermissionError แต่ผมลองเอาโค้ดมาใส่ใน Visual Studio Code แล้วมันรันได้ปกติ ผมอยากให้อาจารย์ช่วยตรวจสอบและแก้ไขเรื่องการรันโค้ดด้วยครับ”

เหตุผลเพราะว่า นศ เปิดไฟล์ใน /scratch แล้วรัน หรือไม่ก็ save as ใน directory ตัวเองแล้ว รันคำสั่งเลยโดยที่ไม่ได้ shutdown kernal แล้วเปิดใหม่ใน directory ตัวเองก่อน

วิธีการใช้โมดูลที่สร้างขึ้น#

การใช้ฟังก์ชันที่ถูกกำหนดไว้ในโมดูลสามารถทำได้โดยการใช้คำสั่ง import และชื่อโมดูล โดยเขียนในรูปแบบ

import <module_name>

**ชื่อโมดูล <module_name> ** คือชื่อไฟล์โมดูลที่ตัดนามสกุล .py ทิ้งนั่นเอง

และตอนที่จะเรียกฟังก์ชันที่อยู่ในโมดูล ก็สามารถเรียกใช้ได้ในรูปแบบ

<module_name>.<function_name>

ยกตัวอย่างเช่น เรามีไฟล์ factorial.py ซึ่งเป็นไฟล์มีฟังก์ชัน fact() เขียนไว้อยู่ แล้วเราต้องการโหลดโมดูลนี้เข้ามาใช้ โดยอยู่บนสมมติฐานที่ว่า ไฟล์ factorial.py ถูกเก็บอยู่ใน Directory (Folder) เดียวกันไฟล์หลัก (ไฟล์ที่เขียนอยู่นี้)

factorial.py:

# คืนค่ากลับเป็นค่าแฟคทอเรียล n! 
def fact(n):
    prod = 1
    for i in range(1, n + 1):
        prod *= i
    return prod
import factorial

factorial.fact(6)
720

การใช้คำสั่ง from หรือคำสั่ง as ก็เหมือนกับโมดูลที่มีอยู่ทุกประการ

หากต้องการใช้ชื่อเดียวกับชื่อที่กำหนดไว้ในโมดูล ก็สามารถเขียนดังต่อไปนี้โดยใช้คำสั่ง from

from factorial import fact

fact(6)
720

การนำเข้าทั้งหมดโดยการใช้เครื่องหมายสตาร์ * ก็สามารถทำได้ แต่เป็นวิธีที่ไม่แนะนำ

เนื่องจากวิธีดังกล่าวเป็นการนำเข้าออบเจ็กต์ทุกอย่าง (ตัวแปร ฟังก์ชัน คลาส ฯลฯ) ที่มีอยู่ในโมดูลเข้ามาในโปรแกรมหลัก ซึ่ง อาจจะมีชื่อออบเจ็กต์ที่เราไม่รู้ว่ามีอยู่ในโมดูล และชื่อนั้นซ้ำกับชื่อในโปรแกรมหลัก ทำให้เกิดความขัดแย้งกัน (Name conflict, name collision)

from factorial import *

หากคุณต้องการใช้ชื่ออื่น เช่น เนื่องจากชื่อโมดูลยาวเกินไป ก็สามารถตั้งชื่อที่ต้องการด้วยคำสั่ง as

import factorial as f

f.fact(6)
720

หากต้องการเช็คเส้นทางที่เก็บซอสโค๊ด (source code) ของโมดูลที่ import เข้ามา สามารถเรียกดูได้จากตัวแปร __file__

factorial.__file__
'/Users/tube.sc/Data_KMITL/Courses_onMac/2021_Python/PyHTML_v02(No_HW)_4std/factorial.py'

Author#

S.C.

Change Log#

Date

Version

Change Description

25-12-2021

0.1

First edition