Python – modules

og:image

Python – modules

ในการออกแบบโปรแกรมที่มีขนาดใหญ่ขึ้น การจัดระบบของตัวแปร, คำสั่ง, ฟังก์ชันให้อยู่ในรูปแบบที่สืบค้นได้สะดวกนั้นก็มีส่วนสำคัญ การแยกส่วนต่างๆ ของการทำงานที่ซับซ้อนออกเป็นส่วนย่อยๆ แล้วจัดกลุ่มการทำงานเหล่านั้นให้เหมาะสม จะทำให้ลดความซ้ำซ้อนในการเขียนโปรแกรมและใช้เวลาน้อยในการสืบค้นชุดคำสั่งที่ทำงานแบบเดียวกัน

โมดูล(modules) ใช้อ้างถึงไฟล์ที่บรรจุชุดคำสั่ง ซึ่งชุดคำสั่งเหล่านั้นจะถูกรวบรวมไว้ให้อยู่ในที่เดียวกันเพื่อทำงานและเพื่อประมวลผลร่วมกัน ตัวอย่างเช่น ทำการสร้างไฟล์ที่ชื่อ “degree_converter.py” เพื่อให้ไฟล์ดังกล่าวทำการรวบรวมคำสั่งและฟังก์ชันสำหรับทำการแปลงข้อมูลอุณหภูมิในหน่วยต่างๆ โดยไฟล์ดังกล่าวนั้นสามารถจัดเป็นหนึ่งโมดูลได้ โดยชื่อของโมดูลก็คือ “degree_converter” ชื่อเดียวกับชื่อไฟล์

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

ตัวอย่างการเรียกใช้งานโมดูลทั่วไป

  1. สร้างโมดูลสำหรับแปลงอุณหภูมิ โดยสร้างไฟล์ “degree_converter.py”
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    #ฟังก์ชันสำหรับแปลงอุณหภูมิจากหน่วยองศาเซลเซียสเป็นองศาฟาเรนต์ไฮต์
    def convert_temperature_to_fahrenheit(degree_celcius):
    	degree_fahrenheit = degree_celcius * (9.0/5.0) + 32
    	return degree_fahrenheit
    
    # ฟังก์ชันสำหรับแปลงอุณหภูมิจากหน่วยจากองศาฟาเรนต์เป็นไฮต์องศาเซลเซียส
    def convert_temperature_to_celcius(degree_fahrenheit):
    	degree_celcius = (degree_fahrenheit - 32) * (5.0/9.0)
    	return degree_celcius
    

    จากตัวอย่างข้างต้น เราได้ทำการสร้างฟังก์ชันชื่อ
    – convert_temperature_to_fahrenheit
    – convert_fahrenheit_to_celcius
    โดยฟังก์ชันดังกล่าวจะอยู่ในโมดูลชื่อ “degree_converter” ซึ่งเป็นโมดูลที่ทำการบรรจุคำสั่งสำหรับแปลงอุณหภูมิเป็นหน่วยต่างๆ

  2. การเรียกใช้โมดูลใน python console

    เราสามารถนำเข้าตัวแปรและฟังก์ชันของโมดูลใน python console ด้วยคีย์เวิร์ด “import” ในกรณีที่ไฟล์ของโมดูลดังกล่าวอยู่ในโฟลเดอร์เดียวกันกับโฟลเดอร์ที่ทำงานอยู่ใน python console
    ตัวอย่างการใช้งาน

    # เรียกใช้โมดูล degree_converter ใน python console
    >>>import degree_converter
    >>>degree_fahrenheit = degree_converter.convert_temperature_to_fahrenheit(30)
    >>>print(degree_fahrenheit)
    86.0
    

    จากตัวอย่างข้างต้น การนำเข้าโมดูลโดยใช้คำสั่ง import ในรูปแบบดังกล่าวไม่สามารถอ้างถึงชื่อฟังก์ชันที่ระบุในโมดูล “degree_converter” ได้เลยโดยตรง แต่จะทำการเรียกใช้ฟังก์ชันนั้นได้ต้องมีการกับกำกับด้วยชื่อโมดูล “degree_converter” ด้วย การเรียกใช้งานฟังก์ชันในโมดูลจึงต้องทำการอ้างถึงในรูปแบบ “ชื่อโมดูล.ชื่อฟังก์ชัน”

  3. การเรียกใช้โมดูลจากโมดูลอื่น

    เราสามารถนำเข้าตัวแปรและฟังก์ชันของโมดูลจากโมดูลอื่น ด้วยคีย์เวิร์ด “import”
    ตัวอย่างการใช้งาน

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    # ทำการเรียกใช้โมดูล degree_converter จากในโมดูลอื่น
    import degree_converter
    
    # กำหนดตัวแปรเก็บข้อมูลอุณหภูมิในหน่วยองศาเซลเซียส
    degree_celcius = 30 
    
    # ทำการเรียกใช้ฟังก์ชันแปลงอุณหภูมิจากหน่วยเซลเซียสเป็นฟาเรนต์ไฮต์ จากโมดูล degree_converter ซึ่งเป็นชื่อเต็มของโมดูลนั้น
    degree_fahrenheit = degree_converter.convert_temperature_to_fahrenheit( degree_celcius )
    
    print("Temperature %d degree celcius is equal to : %d" % (degree_celcius, degree_fahrenheit) )
    
    # โปรแกรมทำการปรินต์ค่า
    # Temperature 30 degree celcius is equal to : 86
    

    การเรียกใช้ในโมดูลอื่นนั้น ก็ใช้วิธีนำเข้าเช่นเดียวกันกับที่ใช้ใน python console โดยจากตัวอย่างการนำเข้าโมดูลรูปแบบนี้ไม่สามารถอ้างถึงชื่อฟังก์ชันที่ระบุในโมดูล “degree_converter” ได้เลยโดยตรง แต่จะทำการเรียกใช้ฟังก์ชันได้พร้อมกับกำกับด้วยชื่อโมดูลด้วย การเรียกใช้งานฟังก์ชันในโมดูลจึงต้องทำการอ้างถึงในรูปแบบ “ชื่อโมดูล.ชื่อฟังก์ชัน”

นอกจากโมดูลที่สร้างขึ้นเองเช่น โมดูล “degree_converter” จากตัวอย่างข้างต้นแล้ว ใน python เองนั้นมีโมดูลที่ถูกพัฒนาขึ้นมาไว้แล้วและถูกติดตั้งมาพร้อมกับตอนติดตั้งให้เลือกใช้ค่อนข้างมาก โดยโมดูลส่วนใหญ่จะอยู่ในโฟลเดอร์ Lib ของตำแหน่งที่เราได้ทำการติดตั้งภาษา python เอาไว้ วิธีการเรียกใช้โมดูลเหล่านี้ ก็ใช้วิธีนำเข้าแบบเดียวกันกับที่เราทำการเรียกใช้โมดูลที่เราเขียนขึ้นเองใหม่ที่กล่าวถึงไว้ข้างต้น

การเรียกใช้โมดูลในแบบต่างๆ
  1. การเรียกใช้โมดูลโดยการใช้เฉพาะคีย์เวิร์ด import

    เราสามารถนำเข้าโมดูลโดยใช้เฉพาะคีย์เวิร์ด “import” เพื่อนำเข้าตัวแปรและฟังก์ชันของโมดูลนั้น
    ตัวอย่างการใช้งาน

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    # ทำการเรียกใช้โมดูล degree_converter 
    import degree_converter
    
    # กำหนดตัวแปรเก็บข้อมูลอุณหภูมิในหน่วยองศาเซลเซียส
    degree_celcius = 30 
    
    # ทำการเรียกใช้ฟังก์ชันแปลงอุณหภูมิจากหน่วยเซลเซียสเป็นฟาเรนต์ไฮต์ จากโมดูล degree_converter ซึ่งเป็นชื่อเต็มของโมดูลนั้น
    degree_fahrenheit = degree_converter.convert_temperature_to_fahrenheit( degree_celcius )
    
    print("Temperature %d degree celcius is equal to : %d" % (degree_celcius, degree_fahrenheit) )
    
    # โปรแกรมทำการปรินต์ค่า
    # Temperature 30 degree celcius is equal to : 86
    

    การนำเข้าโมดูลด้วยการใช้เฉพาะคีย์เวิร์ด import ในรูปแบบนี้ไม่สามารถอ้างถึงชื่อฟังก์ชันที่ระบุในโมดูล “degree_converter” ได้เลยโดยตรง แต่จะทำการเรียกใช้ฟังก์ชันได้พร้อมกับกำกับด้วยชื่อโมดูลด้วย การเรียกใช้งานฟังก์ชันในโมดูลจึงต้องทำการอ้างถึงในรูปแบบ “ชื่อโมดูล.ชื่อฟังก์ชัน”

  2. วิธีการเรียกใช้โมดูลโดยคีย์เวิร์ด import…as… และทำการตั้งชื่อย่อใหม่ให้โมดูลนั้น
    เราสามารถนำเข้าโมดูลและตั้งชื่อแบบย่อให้ใหม่ เพื่อการเรียกใช้โมดูลในบริบทนั้นจะถูกเรียกโดยใช้ชื่อย่อแทน โดยใช้สั่ง import…as… เพื่อนำเข้าตัวแปรและฟังก์ชันของโมดูลนั้น
    ตัวอย่างการใช้งาน

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    # ทำการเรียกใช้โมดูล degree_converter และตั้งชื่อย่อของโมดูลใหม่ว่า dc ซึ่งจะทำให้สะดวกในการเรียกใช้ภายในโปรแกรม
    import degree_converter as dc
    
    # กำหนดตัวแปรเก็บข้อมูลอุณหภูมิในหน่วยองศาเซลเซียส
    degree_celcius = 30
    
    # ทำการเรียกใช้ฟังก์ชันแปลงอุณหภูมิจากหน่วยเซลเซียสเป็นฟาเรนต์ไฮต์ จากโมดูล degree_converter ซึ่งถูกตั้งชื่อย่อว่า dc
    degree_fahrenheit = dc.convert_temperature_to_fahrenheit( degree_celcius )
    
    print("Temperature %d degree celcius is equal to : %d" % (degree_celcius, degree_fahrenheit) )
    
    # โปรแกรมทำการปรินต์ค่า
    # Temperature 30 degree celcius is equal to : 86
    

    เราได้ทำการเรียกใช้โมดูลและทำการตั้งชื่อแบบย่อให้ใหม่เพื่อทำให้การเขียนโปรแกรมสั้นขึ้น โดยชื่อโมดูล degree_converter เราตั้งชื่อย่อให้ว่า dc และเราจะเรียกใช้งานโมดูลดังกล่าวด้วยชื่อ dc แทน โดยหากเราทำการตั้งชื่อแบบย่อแล้ว ในโปรแกรมของเราก็ต้องเข้าถึงฟังก์ชันของโมดูลแบบใช้ชื่อย่อ หากเราทำการเรียกแบบใช้ชื่อเต็มโปรแกรมจะเกิดข้อผิดพลาดขึ้น

  3. วิธีการเรียกใช้โมดูลโดยคำสั่ง from … import… เพื่อนำเข้าเฉพาะบางฟังก์ชันของโมดูล
    เราสามารถทำการเรียกใช้เฉพาะบางฟังก์ชันภายในโมดูล โดยไม่ต้องนำเข้าฟังก์ชันทั้งหมดของโมดูลได้ด้วยคำสั่ง from … import… ซึ่งการนำเข้าแบบนี้จะทำให้เราสามารถจะอ้างอิงถืงชื่อฟังก์ชันของโมดูลได้โดยตรงโดยไม่ต้องระบุชื่อของโมดูล
    ตัวอย่างการใช้งาน

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    # ทำการเรียกใช้โมดูล degree_converter โดยนำเข้าเฉพาะฟังก์ชัน convert_degree_to_fahrenheit
    from degree_converter import convert_temperature_to_fahrenheit
    
    # กำหนดตัวแปรเก็บข้อมูลอุณหภูมิในหน่วยองศาเซลเซียส
    degree_celcius = 30
    
    # ทำการเรียกใช้ฟังก์ชันแปลงอุณหภูมิจากหน่วยเซลเซียสเป็นฟาเรนต์ไฮต์ ซึ่งการนำเข้าแบบนี้ สามารถเรียกใช้ฟังก์ชันของโมดูลได้เลย โดยไม่ต้องระบุชื่อโมดูล
    degree_fahrenheit = convert_temperature_to_fahrenheit( degree_celcius )
    
    print("Temperature %d degree celcius is equal to : %d" % (degree_celcius, degree_fahrenheit) )
    
    # โปรแกรมทำการปรินต์ค่า
    # Temperature 30 degree celcius is equal to : 86
    

    จากตัวอย่างข้างต้น เมื่อเราใช้คำสั่ง from…import… เพื่อนำเข้าเฉพาะบางฟังก์ชันของโมดูลใดๆแล้วในที่นี้ก็คือเฉพาะฟังก์ชัน “convert_temperature_to_fahrenheit” เมื่อเวลาอ้างถึงฟังก์ชันในโมดูลนั้น เราไม่จำเป็นต้องระบุชื่อโมดูลอีก แต่จะเรียกใช้ตามชื่อฟังก์ชันนั้นได้โดยตรง แต่เราจะสามารถเข้าถึงเฉพาะฟังก์ชันที่เราทำการ import มาเท่านั้น ไม่สามารถเรียกใช้ฟังก์ชันอื่นในโมดูลได้

  4. วิธีการเรียกใช้โมดูลโดยคำสั่ง from … import * เพื่อนำเข้าตัวแปรและฟังก์ชันทั้งหมดของโมดูล
    การเรียกใช้โมดูลแบบนี้จะสามารถเข้าถึงตัวแปรและฟังก์ชันที่หมดที่ไม่นำหน้าด้วย “_” และยังสามารถเรียกใช้ตัวแปรและฟังก์ชันดังกล่าวโดยไม่ต้องอ้างถึงชื่อโมดูลอีกด้วย
    ตัวอย่างการใช้งาน

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    # ทำการเรียกใช้โมดูล degree_converter โดยนำเข้าตัวแปรและฟังก์ชันทั้งหมดจากโมดูล
    from degree_converter import *
    
    # กำหนดตัวแปรเก็บข้อมูลอุณหภูมิในหน่วยองศาเซลเซียส
    degree_celcius = 30
    
    # ทำการเรียกใช้ฟังก์ชันแปลงอุณหภูมิจากหน่วยเซลเซียสเป็นฟาเรนต์ไฮต์ ซึ่งการนำเข้าแบบนี้ สามารถเรียกใช้ฟังก์ชันของโมดูลได้เลย โดยไม่ต้องระบุชื่อโมดูล
    degree_fahrenheit = convert_temperature_to_fahrenheit( degree_celcius )
    
    print("Temperature %d degree celcius is equal to : %d" % (degree_celcius, degree_fahrenheit) )
    
    # โปรแกรมทำการปรินต์ค่า
    # Temperature 30 degree celcius is equal to : 86
    

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

ตำแหน่งของไฟล์ที่เก็บโมดูลของ python

เมื่อเรียกใช้คำสั่ง import นั้น ตัวประมวลผลจะทำการค้นหาโมดูลทั้งหมดที่ถูกสร้างเอาไว้แล้วจากที่ตั้งของไฟล์จากหลายตำแหน่ง โดยตัวแปลภาษาจะเริ่มทำการค้นหาโมดูลจากโมดูลที่ติดตั้งมาพร้อม python ก่อนแล้วจึงตรวจสอบตำแหน่งที่ระบุจากค่าที่อยู่ในตัวแปร “sys.path” โดยจะค้นข้อมูลไปตามลำดับดังนี้
1. จากตำแหน่งปัจจุบัน
2. จากตัวแปร “PYTHONPATH”
3. ตำแหน่งที่ติดตั้ง python

import sys
print(sys.path)
# โปรแกรมทำการปรินต์ค่า
# ['',
# 'C:\\Python33\\Lib\\idlelib',
# 'C:\\Windows\\system32\\python33.zip',
# 'C:\\Python33\\DLLs',
# 'C:\\Python33\\lib',
# 'C:\\Python33',
# 'C:\\Python33\\lib\\site-packages']

เราสามารถทำการเพิ่มหรือเปลี่ยแปลงลิสต์ของตำแหน่งที่บรรจุค่าเหล่านี้ได้เช่นกัน

การเรียกคำสั่งนำเข้าโมดูลเดิมหลายครั้ง

ตัวแปลภาษานั้น จะทำการนำเข้าโมดูลหนึ่งๆ เพียงแค่ครั้งเดียวใน session เดียวกัน หากเราเขียนคำสั่งนำเข้าโมดูลตัวเดียวกันหลายครั้ง ตัวแปลภาษาก็จะทำการนำเข้าเพียงโมดูลนั้นเพียงครั้งแค่ครั้งเดียวเท่านั้น

  • สร้างโมดูลชื่อ “MyTest.py”
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    # บรรจุคำสั่งของโมดูล "MyTest.py"
    print("my test exam")
    
  • ทำการเรียกใช้โมดูล “MyTest.py” ใน python console
    # ทำการเรียกใช้โมดูล "MyTest.py" ใน python console
    >>>import MyTest
    my test exam
    >>>import MyTest
    >>>import MyTest
    

    จากตัวอย่างข้างต้น เราทำการเรียกคำสั่งเพื่อนำเข้าโมดูล “MyTest.py” 3 ครั้ง แต่จะเห็นว่า มีการนำเข้าโมดูลดังกล่าวจริงเพียงแค่ครั้งแรกครั้งเดียว ด้วยการพิมพ์ข้อมูลที่บรรจุอยู่ในโมดูลซึ่งเป็นคำสั่งของโมดูลนั้นออกมา และการนำเข้าครั้งอื่นๆ หลังจากนั้นก็จะไม่ถูกดำเนินการ

การเรียกคำสั่งเพื่อให้นำเข้าโมดูลเดิมใหม่(reload)
ในกรณีเรามีการทำการแก้ไขโมดูลต้นทางซึ่งเรานำเข้ามาใช้งานนั้น ตัวโปรแกรมจะไม่ทำการอัพเดทข้อมูลโมดูลต้นทางที่มีการแก้ไขให้อัตโนมัติ แต่เราสามารถสั่งให้โหลดโมดูลใหม่อีกครั้งได้ด้วยฟังก์ชัน “reload” จากโมดูล “imp”
ตัวอย่างการใช้งานใน python console

# ทำการเรียกใช้ใน python console

# นำเข้าโมดูล "imp"
>>>import imp

# นำเข้าโมดูล "MyTest"
>>>import MyTest
my test exam

# ทำการแก้ไขคำสั่งในโมดูล "MyTest" ให้ทำการปรินต์ค่า "Hello world!"
>>>import MyTest

# ลองเรียกคำสั่งนำเข้าโมดูล "MyTest" ใหม่ โดยโปรแกรมยังคงเรียกใช้โมดูลเดิมและยังไม่รับรู้ถึงการเปลี่ยนแปลง
>>>import MyTest

# ทำการเรียกคำสั่ง reload เพื่อนำเข้าโมดูลใหม่อีกครั้ง และโปรแกรมจะสามารถเรียกใช้คำสั่งใหม่ที่ถูกทำการแก้ไข
>>>imp.reload(MyTest)
Hello world!
<module 'MyTest' from '.\\MyTest.py'>

การใช้ฟังก์ชัน dir() เพื่อดูรายละเอียดของโมดูล
เราสามารถใช้ฟังก์ชัน dir() เพื่อจะดูรายละเอียดของชื่อตัวแปรและฟังก์ชันที่ถูกประกาศเอาไว้ให้เรียกใช้ภายในโมดูล เช่นในโมดูลชื่อ “degree_converter” เราได้ทำการสร้างฟังก์ชันเพิ่มคือ “convert_celcius_to_fahrenheit” และฟังก์ชัน “convert_fahrenheit_to_celcius” เอาไว้
ตัวอย่างการใช้งาน

# ทำการเรียกใช้คำสั่ง dir เพื่อดูตัวแปรและฟังก์ชันในโมดูล "degree_converter" ใน python console
>>>dir(degree_converter)
# โปรแกรมทำการปรินต์ค่า
# ['__builtins__',
# '__cached__',
# '__doc__',
# '__file__',
# '__initializing__',
# '__loader__',
# '__name__',
# '__package__',
# 'convert_celcius_to_fahrenheit',
# 'convert_fahrenheit_to_celcius']

จากตัวอย่าง เมื่อเรียกใชัฟังก์ชัน dir เพื่อดูรายชื่อตัวแปรและคำสั่งภายในโมดูล degree_converter แล้ว โปรแกรมจะทำการลิสต์ชื่อและฟังก์ชันที่สามารถเรียกใช้ได้ โดยชื่อที่เริ่มต้นต้วย “_” นั้นจะเป็น attribute ของโมดูลที่สร้างขึ้นมาให้เองอัตโนมัติตอนสร้างโมดูลใหม่ ตัวอย่างเช่น attribute “__name__” จะเป็น attribute ของโมดูลที่ใช้ระบุข้อมูลของชื่อโมดูล
ตัวอย่างการใช้งาน

>>> import degree_converter as dc
>>> dc.__name__
'degree_converter'

จากตัวอย่าง เป็นการเรียกใช้โมดูล degree_converter แล้วตั้งชื่อย่อให้โมดูลว่า dc ใน python console ซึ่งจากตัวอย่างก่อนหน้า เราทราบแล้วว่าทุกโมดูลที่ถูกสร้างขึ้นของ python จะมี attributeชื่อว่า “__name__” ซึ่งจะระบุชื่อเต็มของโมดูลนั้น แล้วจึงทำการเรียกดูข้อมูลของชื่อโมดูลดังกล่าว