ในการรับตำแหน่ง (เส้นทาง) ของไฟล์สคริปต์ที่ทำงานอยู่ใน Python ให้ใช้ __file__ ซึ่งมีประโยชน์สำหรับการโหลดไฟล์อื่นๆ ตามตำแหน่งของไฟล์ที่รันอยู่
มากถึง Python 3.8 __file__ ส่งคืนเส้นทางที่ระบุเมื่อดำเนินการคำสั่ง python (หรือคำสั่ง python3 ในบางสภาพแวดล้อม) หากระบุพาธสัมพัทธ์ เส้นทางสัมพัทธ์จะถูกส่งคืน หากระบุพาธสัมบูรณ์ เส้นทางสัมบูรณ์จะถูกส่งคืน
ใน Python 3.9 และใหม่กว่า เส้นทางสัมบูรณ์จะถูกส่งกลับโดยไม่คำนึงถึงเส้นทางที่ระบุที่รันไทม์
เนื้อหาต่อไปนี้จะอธิบาย
os.getcwd()
,__file__
- รับชื่อไฟล์และชื่อไดเร็กทอรีของไฟล์ที่กำลังดำเนินการอยู่
- รับเส้นทางที่แน่นอนของไฟล์ที่กำลังดำเนินการ
- อ่านไฟล์อื่นๆ ตามตำแหน่งของไฟล์ที่กำลังดำเนินการอยู่
- ย้ายไดเร็กทอรีปัจจุบันไปยังไดเร็กทอรีของไฟล์ที่กำลังดำเนินการ
- การประมวลผลเดียวกันสามารถทำได้โดยไม่คำนึงถึงไดเร็กทอรีปัจจุบันขณะรันไทม์
ดูบทความต่อไปนี้สำหรับข้อมูลเกี่ยวกับการรับและเปลี่ยนไดเร็กทอรีปัจจุบัน (ไดเร็กทอรีการทำงาน)
- บทความที่เกี่ยวข้อง:รับและเปลี่ยน (ย้าย) ไดเร็กทอรีปัจจุบันใน Python
โปรดทราบว่า __file__ ไม่สามารถใช้ได้ใน Jupyter Notebook (.ipynb)
ไดเร็กทอรีที่ .ipynb ตั้งอยู่จะถูกดำเนินการเป็นไดเร็กทอรีปัจจุบัน โดยไม่คำนึงถึงไดเร็กทอรีที่ Jupyter Notebook เริ่มทำงาน
เป็นไปได้ที่จะใช้ os.chdir() ในโค้ดเพื่อเปลี่ยนไดเร็กทอรีปัจจุบัน
- os.getcwd() และ __file__
- รับชื่อไฟล์และชื่อไดเร็กทอรีของไฟล์ที่กำลังดำเนินการอยู่
- รับเส้นทางที่แน่นอนของไฟล์ที่กำลังดำเนินการ
- อ่านไฟล์อื่นๆ ตามตำแหน่งของไฟล์ที่กำลังดำเนินการอยู่
- ย้ายไดเร็กทอรีปัจจุบันไปยังไดเร็กทอรีของไฟล์ที่กำลังดำเนินการ
- การประมวลผลเดียวกันสามารถทำได้โดยไม่คำนึงถึงไดเร็กทอรีปัจจุบันขณะรันไทม์
os.getcwd() และ __file__
ใน Windows คุณสามารถใช้คำสั่ง dir แทน pwd เพื่อตรวจสอบไดเร็กทอรีปัจจุบัน
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook
สร้างไฟล์สคริปต์ Python (file_path.py) โดยมีเนื้อหาต่อไปนี้ในระดับล่าง (data\src)
import os
print('getcwd: ', os.getcwd())
print('__file__: ', __file__)
รันคำสั่ง python (หรือคำสั่ง python3 ในบางสภาพแวดล้อม) โดยระบุพาธไปยังไฟล์สคริปต์
python3 data/src/file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__: data/src/file_path.py
พาธสัมบูรณ์ไปยังไดเร็กทอรีปัจจุบันสามารถรับได้ด้วย os.getcwd() คุณยังสามารถใช้ __file__ เพื่อรับเส้นทางที่ระบุโดยคำสั่ง python3
จนถึง Python 3.8 __file__ จะมีเส้นทางที่ระบุในคำสั่ง python (หรือ python3) ในตัวอย่างข้างต้น เส้นทางสัมพัทธ์ถูกส่งกลับเนื่องจากเป็นเส้นทางสัมพัทธ์ แต่เส้นทางสัมบูรณ์จะถูกส่งกลับหากเป็นเส้นทางแบบสัมบูรณ์
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook
python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
Python 3.9 และใหม่กว่าจะคืนค่าพาธสัมบูรณ์ไปยัง __file__ โดยไม่คำนึงถึงพาธที่ระบุในคำสั่ง python (หรือ python3)
ในตัวอย่างต่อไปนี้ เราจะเพิ่มโค้ดลงในไฟล์สคริปต์เดียวกัน (file_path.py) ใน Python 3.7 และเรียกใช้โดยสัมพันธ์กับไดเร็กทอรีด้านบน
ใน Python 3.7 ใช้เส้นทางที่แน่นอน ผลลัพธ์จะแสดงอยู่ที่ส่วนท้ายของส่วนนี้
รับชื่อไฟล์และชื่อไดเร็กทอรีของไฟล์ที่กำลังดำเนินการอยู่
ในการรับชื่อไฟล์และชื่อไดเร็กทอรีของไฟล์ที่กำลังรันอยู่ ให้ใช้ฟังก์ชันต่อไปนี้ในโมดูล os.path ของไลบรารีมาตรฐาน
os.path.basename()
os.path.dirname()
print('basename: ', os.path.basename(__file__))
print('dirname: ', os.path.dirname(__file__))
ผลการดำเนินการ
# basename: file_path.py
# dirname: data/src
รับเส้นทางที่แน่นอนของไฟล์ที่กำลังดำเนินการ
หากได้รับพาธสัมพัทธ์ด้วย __file__ จะสามารถแปลงเป็นพาธสัมบูรณ์ด้วย os.path.abspath() ไดเร็กทอรียังสามารถได้รับเป็นเส้นทางที่แน่นอน
print('abspath: ', os.path.abspath(__file__))
print('abs dirname: ', os.path.dirname(os.path.abspath(__file__)))
ผลการดำเนินการ
# abspath: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
หากมีการระบุเส้นทางที่แน่นอนใน os.path.abspath() เส้นทางนั้นจะถูกส่งคืนตามที่เป็นอยู่ ดังนั้น หาก __file__ เป็นพาธสัมบูรณ์ ต่อไปนี้จะไม่ทำให้เกิดข้อผิดพลาด
os.path.abspath(__file__)
อ่านไฟล์อื่นๆ ตามตำแหน่งของไฟล์ที่กำลังดำเนินการอยู่
หากคุณต้องการอ่านไฟล์อื่นๆ ตามตำแหน่ง (พาธ) ของไฟล์ที่กำลังดำเนินการ ให้เข้าร่วมสองไฟล์ต่อไปนี้โดยใช้ os.path.join()
- ไดเร็กทอรีของไฟล์ที่กำลังดำเนินการ
- พาธสัมพัทธ์ไปยังไฟล์ที่จะอ่านจากไฟล์ที่รันอยู่
หากคุณต้องการอ่านไฟล์ในไดเร็กทอรีเดียวกันกับไฟล์ที่คุณกำลังรันอยู่ เพียงแค่เชื่อมชื่อไฟล์เข้าด้วยกัน
print('[set target path 1]')
target_path_1 = os.path.join(os.path.dirname(__file__), 'target_1.txt')
print('target_path_1: ', target_path_1)
print('read target file:')
with open(target_path_1) as f:
print(f.read())
ผลการดำเนินการ
# [set target path 1]
# target_path_1: data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
ระดับบนจะแสดงด้วย “. \” คุณสามารถปล่อยให้มันเป็นอยู่ แต่คุณสามารถใช้ os.path.normpath() เพื่อทำให้เส้นทางปกติและลบ “. \” และอักขระอื่น ๆ ออก
print('[set target path 2]')
target_path_2 = os.path.join(os.path.dirname(__file__), '../dst/target_2.txt')
print('target_path_2: ', target_path_2)
print('normalize : ', os.path.normpath(target_path_2))
print('read target file:')
with open(target_path_2) as f:
print(f.read())
ผลการดำเนินการ
# [set target path 2]
# target_path_2: data/src/../dst/target_2.txt
# normalize : data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
ย้ายไดเร็กทอรีปัจจุบันไปยังไดเร็กทอรีของไฟล์ที่กำลังดำเนินการ
ใช้ os.chdir() เพื่อย้ายไดเร็กทอรีปัจจุบันไปยังไดเร็กทอรีของไฟล์ที่กำลังดำเนินการในสคริปต์
- บทความที่เกี่ยวข้อง:รับและเปลี่ยน (ย้าย) ไดเร็กทอรีปัจจุบันใน Python
คุณจะเห็นว่ามันถูกย้ายโดย os.getcwd()
print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print('getcwd: ', os.getcwd())
ผลการดำเนินการ
# [change directory]
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
เมื่อไดเร็กทอรีปัจจุบันถูกย้ายแล้ว ไม่จำเป็นต้องต่อไดเร็กทอรีกับไดเร็กทอรีของไฟล์ที่รันอยู่เมื่ออ่านไฟล์ คุณสามารถระบุพาธที่สัมพันธ์กับไดเร็กทอรีของไฟล์ที่รันอยู่ได้
print('[set target path 1 (after chdir)]')
target_path_1 = 'target_1.txt'
print('target_path_1: ', target_path_1)
print('read target file:')
with open(target_path_1) as f:
print(f.read())
print()
print('[set target path 2 (after chdir)]')
target_path_2 = '../dst/target_2.txt'
print('target_path_2: ', target_path_2)
print('read target file:')
with open(target_path_2) as f:
print(f.read())
ผลการดำเนินการ
# [set target path 1 (after chdir)]
# target_path_1: target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2 (after chdir)]
# target_path_2: ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
การประมวลผลเดียวกันสามารถทำได้โดยไม่คำนึงถึงไดเร็กทอรีปัจจุบันขณะรันไทม์
ดังที่เราได้แสดงให้เห็น เป็นไปได้ที่จะโหลดไฟล์ตามตำแหน่งของไฟล์สคริปต์ โดยไม่ขึ้นกับไดเร็กทอรีปัจจุบันขณะรันไทม์ โดยใช้หนึ่งในวิธีต่อไปนี้
- เชื่อมไดเร็กทอรีของไฟล์ที่รันอยู่และพาธสัมพัทธ์ไปยังไฟล์ที่จะอ่านจากไฟล์ที่รันอยู่โดยใช้ os.path.join()
- ย้ายไดเร็กทอรีปัจจุบันไปยังไดเร็กทอรีของไฟล์ที่กำลังดำเนินการ
การย้ายไดเร็กทอรีปัจจุบันง่ายกว่า แต่แน่นอน หากคุณต้องการอ่านหรือเขียนไฟล์เพิ่มเติมหลังจากนั้น คุณต้องคำนึงว่าไดเร็กทอรีปัจจุบันถูกย้ายแล้ว
ผลลัพธ์ของตัวอย่างก่อนหน้านี้สรุปได้ด้านล่าง
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook
python3 data/src/file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__: data/src/file_path.py
# basename: file_path.py
# dirname: data/src
# abspath: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1]
# target_path_1: data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2]
# target_path_2: data/src/../dst/target_2.txt
# normalize : data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
#
# [change directory]
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1 (after chdir)]
# target_path_1: target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2 (after chdir)]
# target_path_2: ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
ผลลัพธ์ของการระบุเส้นทางที่แน่นอนมีดังนี้
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook
python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# basename: file_path.py
# dirname: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# abspath: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1]
# target_path_1: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2]
# target_path_2: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/../dst/target_2.txt
# normalize : /Users/mbp/Documents/my-project/python-snippets/notebook/data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
#
# [change directory]
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1 (after chdir)]
# target_path_1: target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2 (after chdir)]
# target_path_2: ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
ผลลัพธ์ของการย้ายไดเร็กทอรีปัจจุบันในเทอร์มินัลและรันไฟล์สคริปต์เดียวกันแสดงอยู่ด้านล่าง คุณจะเห็นว่าไฟล์เดียวกันสามารถอ่านได้แม้ว่าจะเรียกใช้จากตำแหน่งอื่นก็ตาม
cd data/src
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
python3 file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# __file__: file_path.py
# basename: file_path.py
# dirname:
# abspath: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1]
# target_path_1: target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2]
# target_path_2: ../dst/target_2.txt
# normalize : ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
#
# [change directory]
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
#
# [set target path 1 (after chdir)]
# target_path_1: target_1.txt
# read target file:
# !! This is "target_1.txt" !!
#
# [set target path 2 (after chdir)]
# target_path_2: ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!