Jeśli nadal szukasz na tej stronie, zaktualizuj poprawną odpowiedź na to . Jest o wiele czystszy niż proponowane rozwiązanie i działa również w przypadkach, gdy __file__nie jest ustawiony.
erikbwork,
3
@ erikb85: to nie tylko czystsze; inspectoparte na rozwiązaniu działa również w execfile()przypadku, gdy __file__cicha nazwa jest niepoprawna.
odpowiada to, jak uzyskać ścieżkę do modułu, który importujesz, ale nie modułu, w którym się znajdujesz (dla skryptu, który uruchamiasz, __file__nie jest to pełna ścieżka, jest względna). Dla pliku, w którym jestem, musiałem zaimportować kolejny moduł z tego samego katalogu i zrobić, jak pokazano tutaj. Czy ktoś zna wygodniejszy sposób?
Ben Bryant
5
@hbdgaf całkiem pewne, że nie ma czegoś takiego jak wbudowanyself.__file__
Dan Passaro
26
@BenBryant @hbdgaf os.path.dirname(__file__)działa dla mnie dobrze i zwraca ścieżkę abs katalogu modułu.
Niccolò,
9
Próbowałem to zrobić i uzyskać informacje zwrotne: AttributeError: 'module' object has no attribute '__file__'
Dorian Dore,
5
@DorianDore Trochę bałaganiłem moduły i path = module.__path__.__dict__["_path"][0]znalazłem rozwiązanie , ale nie jestem pewien, czy jest przenośny, czy też nie różni się między wersjami Pythona. Działa dla mnie, w przeciwieństwie do tej odpowiedzi, która daje ten sam błąd, a inspectodpowiedź podnosi TypeError: <module 'module' (namespace)> is a built-in module...
Moduł inspekcji udostępnia kilka przydatnych funkcji, które pomagają uzyskać informacje o obiektach aktywnych, takich jak moduły, klasy, metody, funkcje, elementy śledzące, obiekty ramek i obiekty kodu. Na przykład może pomóc zbadać zawartość klasy, pobrać kod źródłowy metody, wyodrębnić i sformatować listę argumentów dla funkcji lub uzyskać wszystkie informacje potrzebne do wyświetlenia szczegółowego śledzenia.
Przykład:
>>>import os
>>>import inspect
>>> inspect.getfile(os)'/usr/lib64/python2.7/os.pyc'>>> inspect.getfile(inspect)'/usr/lib64/python2.7/inspect.pyc'>>> os.path.dirname(inspect.getfile(inspect))'/usr/lib64/python2.7'
Google to pytanie wiele razy i to jest najbardziej rozsądna odpowiedź, jaką kiedykolwiek widziałem! Zaktualizuj informacje oinspect.currentframe()
erikbwork,
inspect.getfile()podejście nie działa z modułem _io, ale współpracuje z modułem io.
smwikipedia,
70
Jak powiedziano w innych odpowiedziach, najlepszym sposobem na to jest __file__(pokazane ponownie poniżej). Istnieje jednak ważne zastrzeżenie, które __file__NIE istnieje, jeśli moduł jest uruchamiany samodzielnie (tj. As __main__).
Załóżmy na przykład, że masz dwa pliki (oba na PYTHONPATH):
#/path1/foo.pyimport bar
print(bar.__file__)
i
#/path2/bar.pyimport os
print(os.getcwd())print(__file__)
Uruchomienie foo.py da wynik:
/path1 # "import bar" causes the line "print(os.getcwd())" to run/path2/bar.py # then "print(__file__)" runs/path2/bar.py # then the import statement finishes and "print(bar.__file__)" runs
JEDNAK jeśli spróbujesz uruchomić bar.py na własną rękę, otrzymasz:
/path2 # "print(os.getcwd())" still works fineTraceback(most recent call last):# but __file__ doesn't exist if bar.py is running as mainFile"/path2/bar.py", line 3,in<module>print(__file__)NameError: name '__file__'isnot defined
Mam nadzieję że to pomoże. To zastrzeżenie kosztowało mnie dużo czasu i zamieszania podczas testowania innych przedstawionych rozwiązań.
W takim przypadku możesz użyć sys.argv [0] zamiast pliku .
Jimothy
4
Czy to zastrzeżenie dotyczące konkretnej wersji? W wersjach 2.6 i 2.7 z powodzeniem korzystam z pliku , który działa na pliku o nazwie __ == '__ main '. Jedyny przypadek niepowodzenia, jaki widziałem, to „python -c 'print file '”. Dodam, że czasami plik może mieć wartość <stdin>, co dzieje się, gdy IDE, takie jak emacs, wykonują bieżący bufor.
Paul Du Bois,
1
Zwróć uwagę, że wiodące i końcowe znaki „__” pogrubiają słowo, więc pamiętaj o tym podczas czytania poprzednich komentarzy :-P
Paul Du Bois
1
@PaulDuBois Możesz go otoczyć za pomocą tików tylnych: ` __file__` staje się__file__
fncomp
1
Jak zdobyć NameError? @Paul Du Bois: Próbowałem Python 2.3-3.4 i __file__definiuje jednak uruchomić plik Pythona: python a.py, python -ma, ./a.py.
jfs
43
Spróbuję również rozwiązać kilka wariantów tego pytania:
i nazwij to używając ./foo.py, zwróci „./foo.py”. Wywołanie go z innego katalogu (np. Umieść foo.py w pasku katalogu), a następnie wywołanie jednego z nich
python bar/foo.py
lub dodanie shebang i bezpośrednie wykonanie pliku:
bar/foo.py
zwróci „bar / foo.py” ( ścieżka względna ).
Znajdowanie katalogu
Teraz stamtąd, aby uzyskać katalog, os.path.dirname(__file__)może być również trudne. Przynajmniej w moim systemie zwraca pusty ciąg, jeśli wywołasz go z tego samego katalogu co plik. dawny.
# foo.pyimport os
print'__file__ is:', __file__
print'os.path.dirname(__file__) is:', os.path.dirname(__file__)
wyświetli:
__file__ is: foo.py
os.path.dirname(__file__)is:
Innymi słowy, zwraca pusty ciąg, więc nie wydaje się wiarygodny, jeśli chcesz go użyć dla bieżącego pliku (w przeciwieństwie do pliku importowanego modułu). Aby obejść ten problem, możesz zawrzeć go w wywołaniu abspath:
# foo.pyimport os
print'os.path.abspath(__file__) is:', os.path.abspath(__file__)print'os.path.dirname(os.path.abspath(__file__)) is:', os.path.dirname(os.path.abspath(__file__))
Zauważ, że abspath () NIE rozpoznaje dowiązań symbolicznych. Jeśli chcesz to zrobić, użyj zamiast tego realpath (). Na przykład utworzenie dowiązania symbolicznego file_import_testing_link wskazujące na file_import_testing.py, o następującej treści:
import os
print'abspath(__file__)',os.path.abspath(__file__)print'realpath(__file__)',os.path.realpath(__file__)
wykonanie spowoduje wydrukowanie ścieżek bezwzględnych, takich jak:
inspect.getfile (os) jest taki sam jak plik os .__ z kodu: def getfile (obiekt): "" "Sprawdź, w którym źródle lub skompilowanym pliku zdefiniowano obiekt." "" ismodule (obiekt): if hasattr (obiekt, „ plik ”): zwraca obiekt .__ plik__
idanzalz
4
Możesz użyć, inspect.getfile(inspect.currentframe())aby uzyskać ścieżkę do aktualnie uruchomionego skryptu.
jbochi
33
Nie rozumiem, dlaczego nikt o tym nie mówi, ale dla mnie najprostszym rozwiązaniem jest użycie imp.find_module („nazwa modułu”) (dokumentacja tutaj ):
import imp
imp.find_module("os")
Daje krotkę ze ścieżką w drugiej pozycji:
(<open file '/usr/lib/python2.7/os.py', mode 'U' at 0x7f44528d7540>,'/usr/lib/python2.7/os.py',('.py','U',1))
Zaletą tej metody w porównaniu z metodą „inspekcji” jest to, że nie trzeba importować modułu, aby działał, i można użyć ciągu wejściowego. Przydatne przy sprawdzaniu modułów wywoływanych na przykład w innym skrypcie.
EDYCJA :
W python3 importlibmoduł powinien wykonać:
Dokument z importlib.util.find_spec:
Zwraca specyfikację dla określonego modułu.
Najpierw sprawdzane jest sys.modules, aby sprawdzić, czy moduł został już zaimportowany. Jeśli tak, to sys.modules [nazwa]. specyfikacja jest zwracana. Jeśli tak się stanie, zostanie ustawiona wartość Brak, wówczas zgłaszany jest błąd ValueError. Jeśli modułu nie ma w sys.modules, to sys.meta_path jest przeszukiwany w celu znalezienia odpowiedniej specyfikacji z wartością „path” podaną wyszukiwarkom. Żadne nie jest zwracane, jeśli nie można znaleźć specyfikacji.
Jeśli nazwa dotyczy submodułu (zawiera kropkę), moduł nadrzędny jest importowany automatycznie.
Argumenty nazwy i pakietu działają tak samo jak importlib.import_module (). Innymi słowy, względne nazwy modułów (z wiodącymi kropkami) działają.
imp NIE jest amortyzowane w Pythonie 2 (aktualna wersja 2.7.13). imp jest amortyzowany w Pythonie 3 od wersji 3.4. zamiast tego należy użyć importlib w Pythonie 3. Podoba mi się to rozwiązanie, ponieważ działa nawet wtedy, gdy faktyczny import się nie powiedzie (np. Ponieważ moduł 64-bitowy dla silnika 32-bitowego)
mdew
I NAPRAWDĘ fajnie, gdy próbuje znaleźć ścieżkę 64-bitowego narzędzia sqlite3 i import kończy się niepowodzeniem. Doskonały.
rahvin_t,
2
importlib.machinery.PathFinder().find_module("os").get_filename()Najkrótsza alternatywa dla imp.find_moduleznalazłem w Python3 +. Jeśli ktoś szuka użycia importlib.util.find_spec.
Torxed
Ta metoda działa bez importowania faktycznego modułu, co jest świetne, ponieważ używam go do ustalenia, która wersja modułu jest importowana z udostępnionego komputera.
Gouda
19
To było banalne.
Każdy moduł ma __file__zmienną, która pokazuje ścieżkę względną z miejsca, w którym jesteś teraz.
Dlatego uzyskanie katalogu, w którym moduł będzie powiadamiał o tym, jest proste:
Prawie, ale nie całkiem dobrze - plik nie jest „w stosunku do tego, gdzie jesteś teraz”; gdy jest względny (który będzie tylko wtedy, gdy istnieją ścieżki względne w sys.path), to jest relatywny do tego, gdzie byłeś, gdy moduł został załadowany .
Charles Duffy,
17
import os
path = os.path.abspath(__file__)
dir_path = os.path.dirname(path)
nie działa na moim pythonie dla Linuksa 2.6, ponieważ __file__jest to po prostu katalog / test.py, abspath wymaga cwd do uzupełnienia ścieżki, co nie jest pożądanym rezultatem, ale jeśli zaimportujesz moduł, to m.__file__da pożądany wynik.
Ben Bryant,
10
import module
print module.__path__
Pakiety obsługują jeszcze jeden specjalny atrybut __path__. Jest to inicjowane jako lista zawierająca nazwę katalogu zawierającego pakiet __init__.pyprzed wykonaniem kodu w tym pliku. Ta zmienna może być modyfikowana; wpływa to na przyszłe wyszukiwania modułów i podpakietów zawartych w pakiecie.
Chociaż ta funkcja nie jest często potrzebna, można jej użyć do rozszerzenia zestawu modułów znajdujących się w pakiecie.
Spędziłem więc sporo czasu próbując to zrobić za pomocą py2exe. Problem polegał na uzyskaniu podstawowego folderu skryptu, niezależnie od tego, czy był on uruchamiany jako skrypt Pythona, czy jako plik wykonywalny py2exe. Również, aby działało niezależnie od tego, czy było uruchamiane z bieżącego folderu, innego folderu lub (to było najtrudniejsze) ze ścieżki systemowej.
Ostatecznie zastosowałem to podejście, używając sys.frozen jako wskaźnika działania w py2exe:
import os,sys
if hasattr(sys,'frozen'):# only when running in py2exe this exists
base = sys.prefix
else:# otherwise this is a regular python script
base = os.path.dirname(os.path.realpath(__file__))
Jeśli jedynym zastrzeżeniem dotyczącym używania __file__jest bieżący, względny katalog jest pusty (tzn. Gdy działa jako skrypt z tego samego katalogu, w którym znajduje się skrypt), wówczas trywialnym rozwiązaniem jest:
import os.path
mydir = os.path.dirname(__file__)or'.'
full = os.path.abspath(mydir)print __file__, mydir, full
A wynik:
$ python teste.py
teste.py ./home/user/work/teste
Sztuką jest or '.'po dirname()rozmowie. Ustawia katalog jako ., co oznacza katalog bieżący i jest prawidłowym katalogiem dla każdej funkcji związanej ze ścieżką.
Dlatego używanie abspath()nie jest tak naprawdę potrzebne. Ale jeśli i tak go użyjesz, sztuczka nie jest potrzebna: abspath()akceptuje puste ścieżki i poprawnie interpretuje go jako bieżący katalog.
Lepiej zamień kolejność i po prostu użyj, os.path.dirname(os.path.abspath(__file__))ponieważ wtedy nie musisz się martwić o ścieżki względne. Jedna mniejsza szansa na błędy.
szali
3
Chciałbym przyczynić się do jednego wspólnego scenariusza (w Pythonie 3) i zbadać kilka podejść do niego.
Wbudowana funkcja open () akceptuje ścieżkę względną lub bezwzględną jako swój pierwszy argument. Ścieżka względna jest traktowana jako względna do bieżącego katalogu roboczego, dlatego zaleca się podanie bezwzględnej ścieżki do pliku.
Mówiąc prosto, jeśli uruchomić skrypt z następującego kodu, to nie gwarantuje, że example.txtplik zostanie utworzony w tym samym katalogu, w którym znajduje się plik skryptu:
with open('example.txt','w'):pass
Aby naprawić ten kod, musimy uzyskać ścieżkę do skryptu i uczynić go absolutnym. Aby zapewnić absolutną ścieżkę, po prostu używamy funkcji os.path.realpath () . Aby uzyskać ścieżkę do skryptu, istnieje kilka typowych funkcji, które zwracają różne wyniki ścieżki:
os.getcwd()
os.path.realpath('example.txt')
sys.argv[0]
__file__
Obie funkcje os.getcwd () i os.path.realpath () zwracają wyniki ścieżki na podstawie bieżącego katalogu roboczego . Generalnie nie to, czego chcemy. Pierwszym elementem listy sys.argv jest ścieżka skryptu głównego (uruchamianego skryptu) bez względu na to, czy wywołujesz listę w samym skrypcie głównym, czy w którymkolwiek z jego modułów. W niektórych sytuacjach może się przydać. __File__ Zmienna zawiera ścieżkę do modułu, z którego została wywołana.
Poniższy kod poprawnie tworzy plik example.txtw tym samym katalogu, w którym znajduje się skrypt:
Tak więc powyżej musiałem wywołać maincli.py z modułu my_lib_a.py wiedząc, że top_package i maincli.py znajdują się w tym samym katalogu. Oto jak mogę uzyskać ścieżkę do maincli.py:
import sys
import os
import imp
classConfigurationException(Exception):pass# inside of my_lib_a.pydef get_maincli_path():
maincli_path = os.path.abspath(imp.find_module('maincli')[1])# top_package = __package__.split('.')[0]# mod = sys.modules.get(top_package)# modfile = mod.__file__# pkg_in_dir = os.path.dirname(os.path.dirname(os.path.abspath(modfile)))# maincli_path = os.path.join(pkg_in_dir, 'maincli.py')ifnot os.path.exists(maincli_path):
err_msg ='This script expects that "maincli.py" be installed to the '\
'same directory: "{0}"'.format(maincli_path)raiseConfigurationException(err_msg)return maincli_path
Na podstawie postów opublikowanych przez PlasmaBinturong zmodyfikowałem kod.
Jeśli chcesz to zrobić dynamicznie w „programie”, wypróbuj ten kod:
Chodzi mi o to, że możesz nie znać dokładnej nazwy modułu, aby go „zakodować na stałe”. Może być wybrany z listy lub może nie być uruchomiony, aby użyć __pliku__.
(Wiem, nie będzie działać w Pythonie 3)
global modpath
modname ='os'#This can be any module name on the fly#Create a file called "modname.py"
f=open("modname.py","w")
f.write("import "+modname+"\n")
f.write("modpath = "+modname+"\n")
f.close()#Call the file with execfile()
execfile('modname.py')print modpath
<module 'os'from'C:\Python27\lib\os.pyc'>
Próbowałem pozbyć się problemu „globalnego”, ale znalazłem przypadki, w których to nie działało. Myślę, że można wykonać emulację „execfile ()” w Pythonie 3 Ponieważ jest to program, można go łatwo umieścić w metodzie lub module ponowne użycie.
__file__
nie jest ustawiony.inspect
oparte na rozwiązaniu działa również wexecfile()
przypadku, gdy__file__
cicha nazwa jest niepoprawna.import pathlib, module; pathlib.Path(module.__file__).resolve().parent
ToOdpowiedzi:
Poda ścieżkę do załadowanego pliku .pyc, przynajmniej w systemie Mac OS X. Sądzę, że możesz:
Możesz także spróbować:
Aby uzyskać katalog modułu.
źródło
__file__
nie jest to pełna ścieżka, jest względna). Dla pliku, w którym jestem, musiałem zaimportować kolejny moduł z tego samego katalogu i zrobić, jak pokazano tutaj. Czy ktoś zna wygodniejszy sposób?self.__file__
os.path.dirname(__file__)
działa dla mnie dobrze i zwraca ścieżkę abs katalogu modułu.AttributeError: 'module' object has no attribute '__file__'
path = module.__path__.__dict__["_path"][0]
znalazłem rozwiązanie , ale nie jestem pewien, czy jest przenośny, czy też nie różni się między wersjami Pythona. Działa dla mnie, w przeciwieństwie do tej odpowiedzi, która daje ten sam błąd, ainspect
odpowiedź podnosiTypeError: <module 'module' (namespace)> is a built-in module
...W
inspect
pythonie jest moduł.Oficjalna dokumentacja
Przykład:
źródło
inspect
aby uzyskać nazwę bieżącego pliku; patrz stackoverflow.com/a/50905/320036inspect.currentframe()
inspect.getfile()
podejście nie działa z modułem_io
, ale współpracuje z modułemio
.Jak powiedziano w innych odpowiedziach, najlepszym sposobem na to jest
__file__
(pokazane ponownie poniżej). Istnieje jednak ważne zastrzeżenie, które__file__
NIE istnieje, jeśli moduł jest uruchamiany samodzielnie (tj. As__main__
).Załóżmy na przykład, że masz dwa pliki (oba na PYTHONPATH):
i
Uruchomienie foo.py da wynik:
JEDNAK jeśli spróbujesz uruchomić bar.py na własną rękę, otrzymasz:
Mam nadzieję że to pomoże. To zastrzeżenie kosztowało mnie dużo czasu i zamieszania podczas testowania innych przedstawionych rozwiązań.
źródło
__file__
` staje się__file__
NameError
? @Paul Du Bois: Próbowałem Python 2.3-3.4 i__file__
definiuje jednak uruchomić plik Pythona:python a.py
,python -ma
,./a.py
.Spróbuję również rozwiązać kilka wariantów tego pytania:
(Niektóre z tych pytań zostały zadane na SO, ale zostały zamknięte jako duplikaty i przekierowane tutaj).
Ostrzeżenia dotyczące używania
__file__
W przypadku zaimportowanego modułu:
zwróci bezwzględną ścieżkę modułu. Biorąc jednak pod uwagę następujący skrypt foo.py:
Wywołanie go za pomocą „python foo.py” zwróci po prostu „foo.py”. Jeśli dodasz shebang:
i nazwij to używając ./foo.py, zwróci „./foo.py”. Wywołanie go z innego katalogu (np. Umieść foo.py w pasku katalogu), a następnie wywołanie jednego z nich
lub dodanie shebang i bezpośrednie wykonanie pliku:
zwróci „bar / foo.py” ( ścieżka względna ).
Znajdowanie katalogu
Teraz stamtąd, aby uzyskać katalog,
os.path.dirname(__file__)
może być również trudne. Przynajmniej w moim systemie zwraca pusty ciąg, jeśli wywołasz go z tego samego katalogu co plik. dawny.wyświetli:
Innymi słowy, zwraca pusty ciąg, więc nie wydaje się wiarygodny, jeśli chcesz go użyć dla bieżącego pliku (w przeciwieństwie do pliku importowanego modułu). Aby obejść ten problem, możesz zawrzeć go w wywołaniu abspath:
która generuje coś takiego:
Zauważ, że abspath () NIE rozpoznaje dowiązań symbolicznych. Jeśli chcesz to zrobić, użyj zamiast tego realpath (). Na przykład utworzenie dowiązania symbolicznego file_import_testing_link wskazujące na file_import_testing.py, o następującej treści:
wykonanie spowoduje wydrukowanie ścieżek bezwzględnych, takich jak:
file_import_tporting_testing -> file_import_testing.py
Korzystanie z inspekcji
@SummerBreeze wspomina o module inspekcji .
Wydaje się, że działa to dobrze i jest dość zwięzłe w przypadku importowanych modułów:
posłusznie zwraca absolutną ścieżkę. Jednak aby znaleźć ścieżkę aktualnie wykonywanego skryptu, nie widziałem sposobu, aby go użyć.
źródło
inspect.getfile(inspect.currentframe())
aby uzyskać ścieżkę do aktualnie uruchomionego skryptu.Nie rozumiem, dlaczego nikt o tym nie mówi, ale dla mnie najprostszym rozwiązaniem jest użycie imp.find_module („nazwa modułu”) (dokumentacja tutaj ):
Daje krotkę ze ścieżką w drugiej pozycji:
Zaletą tej metody w porównaniu z metodą „inspekcji” jest to, że nie trzeba importować modułu, aby działał, i można użyć ciągu wejściowego. Przydatne przy sprawdzaniu modułów wywoływanych na przykład w innym skrypcie.
EDYCJA :
W python3
importlib
moduł powinien wykonać:Dokument z
importlib.util.find_spec
:źródło
importlib.machinery.PathFinder().find_module("os").get_filename()
Najkrótsza alternatywa dlaimp.find_module
znalazłem w Python3 +. Jeśli ktoś szuka użyciaimportlib.util.find_spec
.To było banalne.
Każdy moduł ma
__file__
zmienną, która pokazuje ścieżkę względną z miejsca, w którym jesteś teraz.Dlatego uzyskanie katalogu, w którym moduł będzie powiadamiał o tym, jest proste:
źródło
źródło
__file__
jest to po prostu katalog / test.py, abspath wymaga cwd do uzupełnienia ścieżki, co nie jest pożądanym rezultatem, ale jeśli zaimportujesz moduł, tom.__file__
da pożądany wynik.Źródło
źródło
Narzędzie wiersza polecenia
Możesz go dostosować do narzędzia wiersza poleceń,
Stwórz
/usr/local/bin/python-which
Zrób to
źródło
Spędziłem więc sporo czasu próbując to zrobić za pomocą py2exe. Problem polegał na uzyskaniu podstawowego folderu skryptu, niezależnie od tego, czy był on uruchamiany jako skrypt Pythona, czy jako plik wykonywalny py2exe. Również, aby działało niezależnie od tego, czy było uruchamiane z bieżącego folderu, innego folderu lub (to było najtrudniejsze) ze ścieżki systemowej.
Ostatecznie zastosowałem to podejście, używając sys.frozen jako wskaźnika działania w py2exe:
źródło
możesz po prostu zaimportować moduł, a następnie kliknąć jego nazwę, a uzyskasz pełną ścieżkę
źródło
Jeśli chcesz pobrać ścieżkę katalogu głównego pakietu z dowolnego z jego modułów, działają następujące funkcje (testowane w Pythonie 3.6):
Do głównej
__init__.py
ścieżki można również odwołać się, używając__file__
zamiast niej.Mam nadzieję że to pomoże!
źródło
Jeśli jedynym zastrzeżeniem dotyczącym używania
__file__
jest bieżący, względny katalog jest pusty (tzn. Gdy działa jako skrypt z tego samego katalogu, w którym znajduje się skrypt), wówczas trywialnym rozwiązaniem jest:A wynik:
Sztuką jest
or '.'
podirname()
rozmowie. Ustawia katalog jako.
, co oznacza katalog bieżący i jest prawidłowym katalogiem dla każdej funkcji związanej ze ścieżką.Dlatego używanie
abspath()
nie jest tak naprawdę potrzebne. Ale jeśli i tak go użyjesz, sztuczka nie jest potrzebna:abspath()
akceptuje puste ścieżki i poprawnie interpretuje go jako bieżący katalog.źródło
os.path.dirname(os.path.abspath(__file__))
ponieważ wtedy nie musisz się martwić o ścieżki względne. Jedna mniejsza szansa na błędy.Chciałbym przyczynić się do jednego wspólnego scenariusza (w Pythonie 3) i zbadać kilka podejść do niego.
Wbudowana funkcja open () akceptuje ścieżkę względną lub bezwzględną jako swój pierwszy argument. Ścieżka względna jest traktowana jako względna do bieżącego katalogu roboczego, dlatego zaleca się podanie bezwzględnej ścieżki do pliku.
Mówiąc prosto, jeśli uruchomić skrypt z następującego kodu, to nie gwarantuje, że
example.txt
plik zostanie utworzony w tym samym katalogu, w którym znajduje się plik skryptu:Aby naprawić ten kod, musimy uzyskać ścieżkę do skryptu i uczynić go absolutnym. Aby zapewnić absolutną ścieżkę, po prostu używamy funkcji os.path.realpath () . Aby uzyskać ścieżkę do skryptu, istnieje kilka typowych funkcji, które zwracają różne wyniki ścieżki:
os.getcwd()
os.path.realpath('example.txt')
sys.argv[0]
__file__
Obie funkcje os.getcwd () i os.path.realpath () zwracają wyniki ścieżki na podstawie bieżącego katalogu roboczego . Generalnie nie to, czego chcemy. Pierwszym elementem listy sys.argv jest ścieżka skryptu głównego (uruchamianego skryptu) bez względu na to, czy wywołujesz listę w samym skrypcie głównym, czy w którymkolwiek z jego modułów. W niektórych sytuacjach może się przydać. __File__ Zmienna zawiera ścieżkę do modułu, z którego została wywołana.
Poniższy kod poprawnie tworzy plik
example.txt
w tym samym katalogu, w którym znajduje się skrypt:źródło
Jeśli chcesz poznać ścieżkę bezwzględną ze skryptu, możesz użyć obiektu Path :
metoda cwd ()
metoda resol ()
źródło
Z modułów pakietu Pythona musiałem odwoływać się do pliku znajdującego się w tym samym katalogu co pakiet. Dawny.
Tak więc powyżej musiałem wywołać maincli.py z modułu my_lib_a.py wiedząc, że top_package i maincli.py znajdują się w tym samym katalogu. Oto jak mogę uzyskać ścieżkę do maincli.py:
Na podstawie postów opublikowanych przez PlasmaBinturong zmodyfikowałem kod.
źródło
Jeśli chcesz to zrobić dynamicznie w „programie”, wypróbuj ten kod:
Chodzi mi o to, że możesz nie znać dokładnej nazwy modułu, aby go „zakodować na stałe”. Może być wybrany z listy lub może nie być uruchomiony, aby użyć __pliku__.
(Wiem, nie będzie działać w Pythonie 3)
Próbowałem pozbyć się problemu „globalnego”, ale znalazłem przypadki, w których to nie działało. Myślę, że można wykonać emulację „execfile ()” w Pythonie 3 Ponieważ jest to program, można go łatwo umieścić w metodzie lub module ponowne użycie.
źródło
Jeśli zainstalowałeś go za pomocą pipa, „pip show” działa świetnie („Lokalizacja”)
$ pip pokaż detektor2
źródło
Oto krótki skrypt bash na wypadek, gdyby był przydatny dla każdego. Chcę tylko móc ustawić zmienną środowiskową, aby móc
pushd
kodować.Przykład powłoki:
źródło