pika ซึ่งมีซับมอดูล ๓ อันชื่อ momo, dudu และ leleimport 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 . แล้วจึงตามด้วย importfrom . 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.py
momo = '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 ก็จะได้ pikaif(__name__ == '__main__'): ลงไปจะมีความหมายว่าโค้ดต่อไปนี้จะทำงานเมื่อไฟล์นี้ถูกรันโดยตรงไม่ใช่ในฐานะมอดูลif(__name__ == '__main__'):
print('หากคุณเห็นข้อความนี้แสดงว่ากำลังรันโปรแกรมนี้โดยตรง')
ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ