Για να λάβετε τη θέση (διαδρομή) ενός τρέχοντος αρχείου δέσμης ενεργειών στην Python, χρησιμοποιήστε το __file__. Αυτό είναι χρήσιμο για τη φόρτωση άλλων αρχείων με βάση τη θέση του τρέχοντος αρχείου.
Μέχρι την Python 3.8, το __file__ επιστρέφει τη διαδρομή που καθορίστηκε κατά την εκτέλεση της εντολής python (ή της εντολής python3 σε ορισμένα περιβάλλοντα). Αν έχει καθοριστεί σχετική διαδρομή, επιστρέφεται η σχετική διαδρομή- αν έχει καθοριστεί απόλυτη διαδρομή, επιστρέφεται η απόλυτη διαδρομή.
Στην Python 3.9 και μεταγενέστερες εκδόσεις, η απόλυτη διαδρομή επιστρέφεται ανεξάρτητα από τη διαδρομή που καθορίζεται κατά την εκτέλεση.
Εξηγούνται τα ακόλουθα περιεχόμενα.
os.getcwd(),__file__- Λήψη του ονόματος αρχείου και του καταλόγου του τρέχοντος αρχείου που εκτελείται.
- Λήψη της απόλυτης διαδρομής του αρχείου που εκτελείται.
- Διαβάζει άλλα αρχεία με βάση τη θέση του τρέχοντος αρχείου που εκτελείται.
- Μετακινήστε τον τρέχοντα κατάλογο στον κατάλογο του αρχείου που εκτελείται.
- Η ίδια επεξεργασία μπορεί να γίνει ανεξάρτητα από τον τρέχοντα κατάλογο κατά την εκτέλεση.
Ανατρέξτε στο ακόλουθο άρθρο για πληροφορίες σχετικά με τη λήψη και την αλλαγή του τρέχοντος καταλόγου (καταλόγου εργασίας).
Σημειώστε ότι το __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() για να μετακινήσετε τον τρέχοντα κατάλογο στον κατάλογο του αρχείου που εκτελείται στο σενάριο.
Μπορείτε να δείτε ότι μετακινείται από την 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" !!


