pika
ซึ่งมีซับมอดูล ๓ อันชื่อ momo
, dudu
และ lele
import pika
pika
ขึ้นมา เพียงแต่ว่าไฟล์ที่จะถูกเรียกมีแค่ __init__.py ซึ่งอยู่ในโฟลเดอร์ pika เท่านั้น ส่วนไฟล์ momo.py, dudu.py และ lele.py จะยังไม่ถูกเรียก ดังนั้นยังไม่สามารถใช้อะไรในซับมอดูลเหล่านี้ได้import
แยกต่างหาก
import pika.momo
import pika.dudu
import pika.lele
import
ทีละอันนั้นจะต้องไปตั้ง import
ภายใน __init__.py.
ดังนั้นหากต้องการสั่ง import
ไฟล์อื่นจากไฟล์ __init__.py จะต้องพิมพ์ from .
แล้วจึงตามด้วย import
from . import momo
from . import dudu
from . import lele
import pika
ในไฟล์หลักที่รันก็จะสามารถเรียกใช้ซับมอดูลทั้งหมดได้from . import momo
from . import dudu
from . import lele
lele
ได้ถึง ๓ แบบ คือ
pika.lele
pika.dudu.lele
pika.momo.dudu.lele
dudu
ก็สามารถเรียกได้ ๒ แบบ คือ
pika.dudu
pika.momo.dudu
dudu
ถูกเรียกให้มาใช้ใน momo
จึงสามารถเรียกผ่าน momo
อีกต่อได้ และ lele
ก็ถูกเรียกใช้ใน dudu
จึงเรียกผ่าน dudu
ได้ และเรียกผ่าน dudu
ที่เรียกผ่าน momo
อีกต่อได้pikapika
ภายในแพ็กเกจหลัก pika
ซึ่งภายในมีมอดูลย่อยชื่อ momomo
, dududu
และ lelele
dududu
จาก momo
ก็จะต้องพิมพ์ใน momo.py ว่าfrom .pikapika import dududu
pikapika
ต้องมีจุดด้วย หมายถึงการอ้างอิงโฟลเดอร์ที่ตัวเองอยู่แล้วเข้าไปในโฟลเดอร์ pikapika อีกทีlele
จาก dududu
ต้องพิมพ์ใน dududu.py ว่า
from .. import lele
..
หมายถึงถอยหลังไปสองขั้น ในที่นี้ถอยออกไปจนถึงโฟลเดอร์ที่มี lele.py อยู่from .. import lele
ValueError: attempted relative import beyond top-level package
import
จะกลายเป็นการ import
ตัวแพ็กเกจ เพราะลำดับความสำคัญมากกว่าimport pika
ไฟล์ __init__.py ในโฟลเดอร์ pika จะทำงาน แทนที่จะเป็นไฟล์ pika.pymomo = 'momotarou'
from pika import momo
import
เข้ามาจะเป็นตัวแปรชื่อ momo
ไมใช่ตัวไฟล์ซับมอดูล momo.pypikapika = 'pikachu'
from pika import pikapika
import
มาได้ก็คือตัวแปรชื่อ pikapika
ไม่ใช่ซับมอดูล pikapika
ที่อยู่ในโฟลเดอร์ย่อย__name__
ชื่อมอดูลหรือแพ็กเกจ__file__
พาธและชื่อไฟล์ของมอดูลหรือแพ็กเกจ ถ้าใช้กับแพ็คเกจจะได้ __init__.py__package__
ชื่อแพ็กเกจของมอดูลหรือแพ็คเกจ__cached__
พาธและชื่อไฟล์ .pyc__path__
พาธของแพ็กเกจ__doc__
ด็อกสตริงของมอดูลหรือแพ็กเกจpika
และซับมอดูล momo
import pika
print(pika.__name__) # ได้ pika
print(pika.__file__) # ได้ <พาธ>/pika/__init__.py
print(pika.__package__) # ได้ pika
print(pika.__cached__) # ได้ <พาธ>/pika/__pycache__/__init__.cpython-311.pyc
print(pika.__doc__) # ได้ None
print(pika.__path__) # ได้ ['<พาธ>/pika']
import pika.momo
print(pika.momo.__name__) # ได้ pika.momo
print(pika.momo.__file__) # ได้ <พาธ>/pika/momo.py
print(pika.momo.__package__) # ได้ pika
print(pika.momo.__cached__) # ได้ <พาธ>/pika/__pycache__/momo.cpython-311.pyc
print(pika.momo.__doc__) # ได้ None
import pika.pikapika
print(pika.pikapika.__file__) # ได้ <พาธ>/pika/pikapika/__init__.py
print(pika.pikapika.__package__) # ได้ pika.pikapika
print(pika.pikapika.__path__) # ได้ ['<พาธ>/pika/pikapika']
__doc__
นั้นจะมาจากการใส่สายอักขระไว้ด้านบรรทัดบนสุดของไฟล์ สำหรับ pika
นั้นต้องใส่ในไฟล์ pika/__init__.py__path__
จะมีเฉพาะที่เป็นตัวแพ็กเกจเท่านั้น ดังนั้นจึงไม่สามารถใช้กับ pika.momo ได้ แต่ใช้กับ pika
และ pika.pikapika
ได้if(__name__ == '__main__'):
อยู่บ่อยๆ__name__
เป็นแอตทริบิวต์ที่จะติดตัวไฟล์ที่ถูกรัน โดย __name__
จะมีค่าเท่ากับ __main__
เมื่อไฟล์นั้นถูกรันโดยตรง__name__
จะมีค่าเป็นชื่อมอดูลนั้น เช่นเราใช้มอดูล pika
อยู่ ถ้าพิมพ์ print(__name__)
ใส่ใน pika/__init__.py ก็จะได้ pika
if(__name__ == '__main__'):
ลงไปจะมีความหมายว่าโค้ดต่อไปนี้จะทำงานเมื่อไฟล์นี้ถูกรันโดยตรงไม่ใช่ในฐานะมอดูลif(__name__ == '__main__'):
print('หากคุณเห็นข้อความนี้แสดงว่ากำลังรันโปรแกรมนี้โดยตรง')
ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ