Buduję prosty skrypt pomocniczy do pracy, który skopiuje kilka plików szablonów z naszej bazy kodu do bieżącego katalogu. Nie mam jednak bezwzględnej ścieżki do katalogu, w którym przechowywane są szablony. Mam ścieżkę względną ze skryptu, ale gdy wywołuję skrypt, traktuje to jako ścieżkę względem bieżącego katalogu roboczego. Czy istnieje sposób, aby określić, że ten względny adres URL pochodzi z lokalizacji skryptu?
python
relative-path
path
baudtack
źródło
źródło
Odpowiedzi:
W pliku ze skryptem chcesz zrobić coś takiego:
To da ci bezwzględną ścieżkę do pliku, którego szukasz. Pamiętaj, że jeśli używasz setuptools, prawdopodobnie powinieneś zamiast tego użyć interfejsu API zasobów pakietu .
AKTUALIZACJA : Odpowiadam na komentarz tutaj, więc mogę wkleić próbkę kodu. :-)
Zakładam, że masz na myśli
__main__
skrypt, kiedy wspominasz o bezpośrednim uruchomieniu pliku. Jeśli tak, wydaje się, że tak nie jest w moim systemie (python 2.5.1 w OS X 10.5.7):Wiem jednak, że istnieją pewne dziwactwa z
__file__
rozszerzeniami C. Na przykład mogę to zrobić na komputerze Mac:Rodzi to jednak wyjątek na moim komputerze z systemem Windows.
źródło
filename = os.path.join(dir, 'relative', 'path', 'to', 'file', 'you' , 'want')
os.path.dirname(__file__)
może podać pusty ciąg, użyjos.path.dirname(os.path.abspath(__file__))
zamiast tegopotrzebujesz
os.path.realpath
(przykład poniżej dodaje katalog nadrzędny do ścieżki)źródło
os.path.dirname(__file__)
dał mi pusty ciąg. To działało idealnie.os.path.realpath('..')
daje katalog macierzysty bieżącego działającego katalogu . Zwykle nie tego chcesz.Jak wspomniano w zaakceptowanej odpowiedzi
Chcę tylko to dodać
Tak powinno być
W niektórych przypadkach zaakceptowana odpowiedź może wprowadzać w błąd. Szczegółowe informacje można znaleźć w tym linku
źródło
os.path.join
jest lepsze, ponieważ łączy je z separatorem specyficznym dla systemu operacyjnego.'/relative/path...'
nie jest ścieżką względną. Czy to celowe?os.path.join()
. Pozostaje preferencja użycia oddzielnych ciągów dla każdego elementu ścieżki zamiast zakodowania separatora ścieżki na stałe.Teraz jest 2018, a Python ewoluował już
__future__
dawno temu. Tak jak o użyciu niesamowitepathlib
pochodzących z Pythona 3.4, aby wykonać zadanie, a nie walczy zos
,os.path
,glob
,shutil
, itd.Mamy tutaj 3 ścieżki (być może zduplikowane):
mod_path
: która jest ścieżką prostego skryptu pomocniczegosrc_path
: który zawiera kilka plików szablonów oczekujących na skopiowanie.cwd
: bieżący katalog , miejsce docelowe tych plików szablonów.problem polega na tym , że nie mamy pełnej ścieżki
src_path
, wiemy tylko, że jest to ścieżka względna domod_path
.Teraz rozwiążmy to za pomocą niesamowitego
pathlib
:W przyszłości będzie to takie proste. :RE
Ponadto możemy wybierać i sprawdzać oraz kopiować / przenosić te pliki szablonów za pomocą
pathlib
:źródło
Rozważ mój kod:
źródło
Zobacz sys.path Zainicjowany podczas uruchamiania programu, pierwszy element tej listy, ścieżka [0], to katalog zawierający skrypt użyty do wywołania interpretera Pythona.
Użyj tej ścieżki jako folderu głównego, z którego zastosujesz ścieżkę względną
źródło
sys.path[0]
nie zawsze jest ustawiony na katalog nadrzędny. Kod Python może być wywołany z-c
lub-m
lub za pośrednictwem wbudowanego tłumacza, w którym momenciesys.path[0]
jest ustawiony na coś innego całkowicie.Zamiast używać
tak jak w zaakceptowanej odpowiedzi, bardziej niezawodne byłoby użycie:
ponieważ użycie __plik_ zwróci plik, z którego moduł został załadowany, jeśli został załadowany z pliku, więc jeśli plik ze skryptem zostanie wywołany z innego miejsca, zwrócony katalog nie będzie poprawny.
Odpowiedzi te zawierają więcej szczegółów: https://stackoverflow.com/a/31867043/5542253 i https://stackoverflow.com/a/50502/5542253
źródło
inspect.stack()
jest kosztowną funkcją do wywołania. Pobiera informacje dla wszystkich ramek stosu, które następnie odrzucasz i otrzymujesz tylko najwyższą. Zasadniczo wywołujeinspect.getfile()
obiekt modułu, który po prostu zwracamodule.__file__
. Lepiej jest po prostu używać__file__
.Cześć, przede wszystkim powinieneś zrozumieć funkcje os.path.abspath (ścieżka) i os.path.relpath (ścieżka)
W skrócie os.path.abspath (ścieżka) tworzy ścieżkę względną do ścieżki bezwzględnej . A jeśli podana ścieżka jest sama ścieżką bezwzględną, wówczas funkcja zwraca tę samą ścieżkę.
podobnie os.path.relpath (ścieżka) tworzy ścieżkę bezwzględną do ścieżki względnej . A jeśli podana ścieżka sama jest ścieżką względną, wówczas funkcja zwraca tę samą ścieżkę.
Poniższy przykład pozwala poprawnie zrozumieć powyższą koncepcję :
Załóżmy, że mam plik lista_plików_wejściowych.txt, który zawiera listę plików wejściowych do przetworzenia przez mój skrypt python.
D: \ conc \ input1.dic
D: \ conc \ input2.dic
D: \ Copyioconc \ lista_plików_wejściowych.txt
Jeśli widzisz powyższą strukturę folderów, lista_plików_plików.txt znajduje się w folderze Copyofconc, a pliki do przetworzenia przez skrypt python znajdują się w folderze conc
Ale zawartość pliku input_file_list.txt jest taka, jak pokazano poniżej:
.. \ conc \ input1.dic
.. \ conc \ input2.dic
A mój skrypt Pythona jest obecny w D: drive.
A ścieżka względna podana w pliku plik_wejściowy.txt jest względna do ścieżki pliku plik_wejściowy.txt .
Więc kiedy skrypt Pythona powinien wykonać bieżący katalog roboczy (użyj os.getcwd () aby uzyskać ścieżkę)
Ponieważ moja ścieżka względna jest względna do listy_pliku_wejściowego.txt , czyli „D: \ Copyofconc” , muszę zmienić bieżący katalog roboczy na „D: \ Copyofconc” .
Więc muszę użyć os.chdir („D: \ Copyofconc”) , więc bieżącym katalogiem roboczym będzie „D: \ Copyofconc” .
Teraz, aby pobrać pliki input1.dic i input2.dic , przeczytam wiersze „.. \ conc \ input1.dic”, a następnie użyję polecenia
input1_path = os.path.abspath ('.. \ conc \ input1.dic') (aby zmienić ścieżkę względną na ścieżkę bezwzględną. Tutaj jako bieżący katalog roboczy jest „D: \ Copyofconc”, plik „. \ conc \ input1. dic ”należy uzyskać w odniesieniu do„ D: \ Copyofconc ”)
więc input1_path będzie mieć postać „D: \ conc \ input1.dic”
źródło
Ten kod zwróci bezwzględną ścieżkę do głównego skryptu.
Działa to nawet w module.
źródło
sys.modules['__main__'].__file__
.Alternatywa, która działa dla mnie:
źródło
To, co zadziałało, to używanie
sys.path.insert
. Następnie określiłem katalog, który powinienem przejść. Na przykład po prostu musiałem przejść o jeden katalog wyżej.źródło
Nie jestem pewien, czy dotyczy to niektórych starszych wersji, ale uważam, że Python 3.3 ma natywną obsługę ścieżek względnych.
Na przykład poniższy kod powinien utworzyć plik tekstowy w tym samym folderze co skrypt Pythona:
(pamiętaj, że na początku nie powinno być ukośnika w przód ani w lewo, jeśli jest to ścieżka względna)
źródło