python: pobierz katalog dwa poziomy wyżej


86

Ok ... nie wiem, gdzie xjest moduł , ale wiem, że muszę uzyskać ścieżkę do katalogu dwa poziomy wyżej.

Czy jest więc bardziej elegancki sposób:

import os
two_up = os.path.dirname(os.path.dirname(__file__))

Mile widziane rozwiązania dla Pythona 2 i 3!


1
Myślę, że twoje rozwiązanie jest w porządku. pathlibRozwiązanie jest trochę ładniejszy i bardziej czytelne, ale nie jest wliczone w Pythonie 2.7. Powiedziałbym, że trzymaj się tego, co masz, może dodaj komentarz.
— jme

Być może warto dodać pip install pathlib2opcję utrzymania rozsądku w 2.7.
— Jonathan

Odpowiedzi:


104

Możesz użyć pathlib. Niestety jest to dostępne tylko w standardowej bibliotece Python 3.4. Jeśli masz starszą wersję, musisz zainstalować kopię z PyPI tutaj . Powinno to być łatwe do zrobienia za pomocą pip.

from pathlib import Path

p = Path(__file__).parents[1]

print(p)
# /absolute/path/to/two/levels/up

Używa parentssekwencji, która zapewnia dostęp do katalogów nadrzędnych i wybiera drugi w górę.

Zauważ, że pw tym przypadku będzie jakaś forma Pathobiektu z własnymi metodami. Jeśli potrzebujesz ścieżek jako łańcuchów, możesz je wywołać str.


To miła odpowiedź, dzięki i świetnie dla py3. W przypadku py2 nie jest to lepsze niż moja pierwsza próba, ponieważ tworzy dodatkową zależność
— jramm

16
Nie powinna to być akceptowana odpowiedź, ponieważ Pathklasa parentszależy od miejsca wykonania. Jeśli wykonasz swój plik __file__z bieżącego katalogu, Pathklasa nie będzie miała rodziców. Albo odpowiedź @ Sebi2020 powinna zostać zaakceptowana, albo powinna zostać użyta Twoja oryginalna metoda. Uważam, że twoja oryginalna metoda jest bardziej czytelna.
— Red-Tune-84

1
Być może będziesz musiał to zrobićp = Path(os.path.abspath(__file__)).parents[1]
— Adam Raudonis

4
@AdamRaudonis Zamiast os.path.abspath, możesz też użyćPath(__file__).resolve().parents[1]
— Tulio Casagrande.

7
Jak wspomniał @Kazanz, to rozwiązanie nie działa podczas wykonywania z innych ścieżek. Najlepszym rozwiązaniem jest: p = Path(__file__).resolve().parents[1]. Dodałem to również jako odpowiedź.
— pythinker

46

Bardzo łatwe:

Oto, czego chcesz:

import os.path as path

two_up =  path.abspath(path.join(__file__ ,"../.."))

8
A może os.pardirraczej użyj niż ...
— jme

sys.argv [0] nie zwraca modułu uruchomionego przez python.exe? Więc nie byłaby to konieczna praca, gdyby moduł, który mnie interesował, został zaimportowany z innej paczki… jestem tutaj?
— jramm

Jeśli chcesz użyć go w module, zamiast tego użyj __file__.
— Sebi2020

1
@jme Czy znasz system operacyjny, w którym uzyskujesz katalog nadrzędny z innym ciągiem znaków niż „..” ???
— Sebi2020,

1
@ Sebi2020 Tak, zwłaszcza stary Mac OS. Oto lista: en.wikipedia.org/wiki/Path_(computing)
— jme

22

Chciałem to dodać, żeby być głupim, ale także dlatego, że pokazuje nowicjuszom potencjalną użyteczność funkcji aliasingu i / lub importu.

Po napisaniu tego uważam, że ten kod jest bardziej czytelny (tj. Krótszy czas na zrozumienie intencji) niż inne dotychczasowe odpowiedzi, a czytelność jest (zwykle) najważniejsza.

from os.path import dirname as up

two_up = up(up(__file__))

Uwaga: chcesz to zrobić tylko wtedy, gdy twój moduł jest bardzo mały lub spójny kontekstowo.


14

Najlepszym rozwiązaniem (dla pythona> = 3.4) podczas wykonywania z dowolnego katalogu jest:

from pathlib import Path
two_up = Path(__file__).resolve().parents[1]

10

Aby uzyskać dostęp do katalogu 2 poziomy w górę:

 import os.path as path
 two_up = path.abspath(path.join(os.getcwd(),"../.."))

4

Osobiście uważam, że użycie modułu os jest najłatwiejszą metodą, jak opisano poniżej. Jeśli przechodzisz tylko o jeden poziom w górę, zamień („../ ..”) na („..”).

    import os
    os.chdir('../..')

--Check:
    os.getcwd()

1
Czy można na stałe zakodować znak „/”, którego spodziewałbym się, że przeczytam os.chdir (os.join („..”, „..”))
— GreenAsJade

2

Zauważyłem, że poniższe działa dobrze w wersji 2.7.x.

import os
two_up = os.path.normpath(os.path.join(__file__,'../'))

1

Możesz użyć tego jako ogólnego rozwiązania:

import os

def getParentDir(path, level=1):
  return os.path.normpath( os.path.join(path, *([".."] * level)) )

@JanSila: może być bardziej szczegółowe, dlaczego nie jest pythonowe? Dla czytelności może mieć więcej komentarzy, co to robi, tak - ale ostatecznie używa standardowych funkcji języka Python, patrz np. Stackoverflow.com/questions/36901
— Axel Heider

Jest trochę gęsty, ale nie sądzę, żeby był zbyt abstrakcyjny i nieczytelny. To tylko uogólniona wersja innych odpowiedzi zamieszczonych tutaj. Chciałbym jednak robić rzeczy w standardowej bibliotece bez potrzeby implementowania funkcji.
— ryanjdillon

1

Bardziej wieloplatformowe wdrożenie będzie:

import pathlib
two_up = (pathlib.Path(__file__) / ".." / "..").resolve()

Używanie parentnie jest obsługiwane w systemie Windows. Należy również dodać .resolve()do:

Uczyń ścieżkę absolutną, rozwiązując wszystkie linki symboliczne po drodze, a także normalizując ją (na przykład zamieniając ukośniki na ukośniki odwrotne w systemie Windows)


2
Czy masz źródło, które parentnie działa w systemie Windows? Wydaje się, że zostało to naprawione jakiś czas temu, odkąd napisałeś ten komentarz. U mnie działa dobrze, używając Pythona 3.7.2 w systemie Windows 10.
— Nathan,

mógłbym zacząć parentpracować na systemie Windows 10 z Pythonem 3.6.5. O której wersji Pythona mówisz @Zhukovgeen?
— ggulgulia

@ggulgulia Myślę, że to było 3,7
— zhukovgreen

0

Zakładając, że chcesz uzyskać dostęp do folderu o nazwie xzy dwa foldery w pliku Pythona. To działa dla mnie i niezależnie od platformy.

„.././xyz”


0

(pathlib.Path ('../../')) .resolve ()


Podaje ścieżkę względem katalogu roboczego, a nie modułu
— jramm

-1

Nie widzę jeszcze realnej odpowiedzi na 2.7, która nie wymaga instalowania dodatkowych zależności, a także zaczyna się od katalogu pliku. Nie jest to przyjemne rozwiązanie jednokreskowe, ale nie ma nic złego w korzystaniu ze standardowych narzędzi.

import os

grandparent_dir = os.path.abspath(  # Convert into absolute path string
    os.path.join(  # Current file's grandparent directory
        os.path.join(  # Current file's parent directory
            os.path.dirname(  # Current file's directory
                os.path.abspath(__file__)  # Current file path
            ),
            os.pardir
        ),
        os.pardir
    )
)

print grandparent_dir

Aby udowodnić, że to działa, zacznę tutaj, ~/Documents/notesaby pokazać, że bieżący katalog nie wpływa na wynik. Umieściłem plik grandpa.pyz tym skryptem w folderze o nazwie „scripts”. Przeszukuje do katalogu Dokumenty, a następnie do katalogu użytkownika na komputerze Mac.

(testing)AlanSE-OSX:notes AlanSE$ echo ~/Documents/scripts/grandpa.py 
/Users/alancoding/Documents/scripts/grandpa.py
(testing)AlanSE-OSX:notes AlanSE$ python2.7 ~/Documents/scripts/grandpa.py 
/Users/alancoding

To oczywista ekstrapolacja odpowiedzi dla rodzica reż . Lepiej jest użyć rozwiązania ogólnego niż mniej dobrego w mniejszej liczbie wierszy.


-1

dla py 3.4 i nowszych, pathlib

przykład:

from pathlib import Path
path = Path("../../data/foo/someting.csv").resolve()

Daje to ścieżkę względem katalogu roboczego, a nie modułu
— jramm
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.