Jak odzyskać ścieżkę modułu?

Chcę wykryć, czy moduł się zmienił. Teraz korzystanie z inotify jest proste, wystarczy znać katalog, z którego chcesz otrzymywać powiadomienia.

Jak odzyskać ścieżkę modułu w Pythonie?

Author: martineau, 2008-10-29

20 answers

import a_module
print(a_module.__file__)

Rzeczywiście da ci drogę do .plik pyc, który został załadowany, przynajmniej na Mac OS X. więc myślę, że możesz to zrobić:

import os
path = os.path.abspath(a_module.__file__)
Możesz również spróbować:
path = os.path.dirname(a_module.__file__)

Aby pobrać katalog modułu.

 1001
Author: orestis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-15 11:13:46

Istnieje inspect moduł w Pythonie.

Oficjalna dokumentacja

Moduł inspect zapewnia kilka przydatnych funkcji, które pomogą uzyskać informacje o żywych obiektach, takich jak moduły, klasy, metody, funkcje, znaczniki, obiekty ramek i Obiekty kodu. Na przykład, może pomóc sprawdzić zawartość klasy, pobrać źródło kod metody, wyodrębnij i sformatuj listę argumentów funkcji, lub uzyskać wszystkie potrzebne informacje, aby wyświetl szczegółowy ślad.

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'
 294
Author: Tomas Tomecek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-28 07:24:09

Jak mówiły inne odpowiedzi, najlepszym sposobem na to jest __file__ (pokazane ponownie poniżej). Istnieje jednak ważne zastrzeżenie, które polega na tym, że __file__ nie istnieje, jeśli moduł jest uruchamiany samodzielnie (np. jako __main__).

Na przykład, powiedzmy, że masz dwa pliki (oba są na twojej ścieżce PYTHONPATH):

#/path1/foo.py
import bar
print(bar.__file__)

I

#/path2/bar.py
import os
print(os.getcwd())
print(__file__)

Bieganie foo.py daje 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że jeśli spróbujesz uruchomić bar.py na własną rękę, będziesz get:

/path2                              # "print(os.getcwd())" still works fine
Traceback (most recent call last):  # but __file__ doesn't exist if bar.py is running as main
  File "/path2/bar.py", line 3, in <module>
    print(__file__)
NameError: name '__file__' is not defined 
Mam nadzieję, że to pomoże. To zastrzeżenie kosztowało mnie dużo czasu i zamieszania podczas testowania innych przedstawionych rozwiązań.
 74
Author: mcstrother,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-20 18:33:21

Postaram się rozwiązać kilka wariacji na ten temat, jak również:

  1. znajdowanie ścieżki wywołanego skryptu
  2. znajdowanie ścieżki aktualnie wykonywanego skryptu
  3. znajdowanie katalogu wywołanego skryptu

(niektóre z tych pytań zostały zadane NA SO, ale zostały zamknięte jako duplikaty i przekierowane tutaj.)

Zastrzeżenia dotyczące używania __file__

Dla zaimportowanego modułu:

import something
something.__file__ 

Zwróci absolutna ścieżka modułu. Jednak biorąc pod uwagę następujący scenariusz foo.py:

#foo.py
print '__file__', __file__

Wywołanie przez 'python foo.py" Will return simply "foo.py'. jeśli dodasz shebang:

#!/usr/bin/python 
#foo.py
print '__file__', __file__

I nazwij to używaniem. /foo.py, powróci". /foo.py'. wywołanie go z innego katalogu, (np. put foo.py w pasku katalogów), następnie wywołanie

python bar/foo.py

Lub dodanie pliku i wykonanie go bezpośrednio:

bar/foo.py

Powróci "bar/foo.py" (the relative ścieżka).

Znajdowanie katalogu

Teraz przejście stamtąd, aby uzyskać katalog, os.path.dirname(__file__) Może być również trudne. Przynajmniej w moim systemie zwraca pusty łańcuch, jeśli wywoła się go z tego samego katalogu co plik. ex.

# foo.py
import 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 łańcuch, więc nie wydaje się to wiarygodne, jeśli chcesz go użyć do bieżącego pliku (W przeciwieństwie do pliku importowanego modułu). Aby to obejść, możesz w tym celu należy wykonać następujące czynności:]}

# foo.py
import 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__))

Co daje coś w rodzaju:

os.path.abspath(__file__) is: /home/user/bar/foo.py
os.path.dirname(os.path.abspath(__file__)) is: /home/user/bar

Zauważ, że abspath () nie rozwiązuje dowiązań symbolicznych. Jeśli chcesz to zrobić, użyj metody realpath (). Na przykład utworzenie dowiązania symbolicznego file_import_testing_link wskazującego 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__)

Executing wyświetli ścieżki absolutne coś w stylu:

abspath(__file__) /home/user/file_test_link
realpath(__file__) /home/user/file_test.py

File_import_testing_link - > file_import_testing.py

Za pomocą inspect

@ SummerBreeze wspomina o użyciu modułuinspect .

Wydaje się, że działa to dobrze i jest dość zwięzłe dla importowanych modułów:]}
import os
import inspect
print 'inspect.getfile(os) is:', inspect.getfile(os)

Posłusznie zwraca ścieżkę absolutną. Aby znaleźć ścieżkę aktualnie wykonywanego skryptu:

inspect.getfile(inspect.currentframe())

(Dzięki @ jbochi)

 45
Author: jpgeek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-08 19:36:18

Nie rozumiem, dlaczego nikt o tym nie mówi, ale dla mnie najprostszym rozwiązaniem jest użycie imp.find_module ("modulename") (documentation tutaj):

import imp
imp.find_module("os")

Daje krotkę ze ścieżką na 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 stosunku do metody" inspect " jest to, że nie musisz importować modułu, aby działał i możesz użyć ciągu znaków w input. Przydatne przy sprawdzaniu modułów wywołanych w innym skrypcie dla przykład.

EDIT :

W python3, importlib moduł powinien wykonać:

Doc z importlib.util.find_spec:

Zwraca specyfikację dla określonego modułu.

Po pierwsze, sys.moduły są sprawdzane, aby sprawdzić, czy moduł został już zaimportowany. Jeśli tak, to sys.Moduły [nazwa]. zwracane jest spec. Jeśli tak się stanie ustawiona na None, wtedy zostanie wywołana wartość ValueError. Jeśli moduł nie jest w sys.moduły, a następnie sys.meta_path wyszukuje odpowiedni spec z wartość "ścieżki" / align = "left" / None jest zwracane, jeśli żadna specyfikacja nie może bądź znaleziony.

Jeśli nazwa jest dla submodule (zawiera kropkę), moduł nadrzędny jest automatycznie importowane.

Nazwa i argumenty pakietu działają tak samo jak importlib.import_module (). Innymi słowy, działają względne nazwy modułów (z wiodącymi kropkami).

 35
Author: PlasmaBinturong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-03 10:30:00

To było trywialne.

Każdy moduł ma zmienną __file__, która pokazuje swoją ścieżkę względną od miejsca, w którym jesteś teraz.

Dlatego uzyskanie katalogu dla modułu do powiadamiania o tym jest proste jak:

os.path.dirname(__file__)
 19
Author: Cheery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-08 11:50:40
import os
path = os.path.abspath(__file__)
dir_path = os.path.dirname(path)
 17
Author: vinoth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-16 20:31:39
import module
print module.__path__

Pakiety obsługują jeszcze jeden specjalny atrybut, __path__. To jest inicjalizowana jako lista zawierająca nazwę katalogu posiadającego Pakiet jest __init__.py przed wykonaniem kodu w tym pliku. Zmienna ta może być modyfikowana; wpływa to na przyszłe poszukiwania moduły i podpakiety zawarte w pakiecie.

Chociaż ta funkcja nie jest często potrzebna, może być używana do rozszerzenia zestaw modułów znalezionych w paczka.

Źródło

 14
Author: Lukas Greblikas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-02 11:14:03

Narzędzie Wiersza Poleceń

Możesz dostosować go do narzędzia wiersza poleceń,

python-which <package name>

Tutaj wpisz opis obrazka


Create /usr/local/bin/python-which

#!/usr/bin/env python

import importlib
import os
import sys

args = sys.argv[1:]
if len(args) > 0:
    module = importlib.import_module(args[0])
    print os.path.dirname(module.__file__)

Make it executable

sudo chmod +x /usr/local/bin/python-which
 9
Author: Jossef Harush,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-03 09:51:54

Możesz po prostu zaimportować swój moduł następnie naciśnij jego nazwę, a otrzymasz jego pełną ścieżkę

>>> import os
>>> os
<module 'os' from 'C:\\Users\\Hassan Ashraf\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\os.py'>
>>>
 7
Author: Hassan Ashraf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-29 15:39:10

Więc spędziłem sporo czasu próbując to zrobić z py2exe Problem polegał na pobraniu folderu bazowego skryptu, niezależnie od tego, czy był on uruchamiany jako skrypt Pythona, czy jako plik wykonywalny py2exe. Również, aby to działało, czy to było uruchamiane z bieżącego folderu, innego folderu lub (to było najtrudniejsze) ze ścieżki systemu.

W końcu użyłem tego podejścia, używając sys.zamrożony jako wskaźnik 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__))
 6
Author: uri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-18 16:28:43

Jeśli chcesz pobrać ścieżkę główną pakietu z dowolnego z jego modułów, działa to następująco (testowane na Pythonie 3.6):

from . import __path__ as ROOT_PATH
print(ROOT_PATH)

Główna ścieżka __init__.py może być również odwołana za pomocą __file__.

Mam nadzieję, że to pomoże!
 5
Author: fr_andres,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-31 23:03:39

Jeśli chcesz poznać ścieżkę bezwzględną ze swojego skryptu możesz użyć Path object:

from pathlib import Path

print(Path().absolute())
print(Path().resolve('.'))
print(Path().cwd())

Metoda Cwd ()

Zwraca nowy obiekt path reprezentujący bieżący katalog (zwracany przez system operacyjny.getcwd ())

Metoda Resolve ()

Ustaw ścieżkę jako absolutną, rozwiązując wszelkie dowiązania symboliczne. Zwracany jest nowy obiekt path:

 4
Author: Vlad Bezden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-06 13:04:45

Jeśli jedynym zastrzeżeniem użycia {[2] } jest to, że katalog bieżący jest pusty (np. gdy jest uruchomiony jako skrypt z tego samego katalogu, w którym znajduje się skrypt), to trywialnym rozwiązaniem jest:

import os.path
mydir = os.path.dirname(__file__) or '.'
full  = os.path.abspath(mydir)
print __file__, mydir, full

I wynik:

$ python teste.py 
teste.py . /home/user/work/teste

The trick is in or '.' after the dirname() call. Ustawia katalog jako ., co oznacza bieżący katalog i jest poprawnym katalogiem dla dowolnej funkcji związanej ze ścieżką.

Dlatego używanie abspath() nie jest naprawdę potrzebne. Ale jeśli i tak go użyjesz, sztuczka polega na tym, że not needed: abspath() akceptuje puste ścieżki i poprawnie interpretuje je jako bieżący katalog.

 3
Author: MestreLion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-15 01:22:39

Chciałbym przyczynić się do jednego wspólnego scenariusza (w Pythonie 3) i zbadać kilka podejść do niego.

Wbudowana funkcja open () przyjmuje jako pierwszy argument ścieżkę względną lub bezwzględną. Ścieżka względna jest traktowana jako względem bieżącego katalogu roboczego , dlatego zaleca się przekazanie bezwzględnej ścieżki do pliku.

Po prostu, jeśli uruchomisz plik skryptu z następującym kodem, to Nie gwarantuje, że example.txt plik 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ć, że ścieżka będzie absolutna, po prostu używamy os./ align = "left" / funkcja realpath(). Aby uzyskać ścieżkę do skryptu, istnieje kilka popularnych 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./ align = "left" / realpath () zwraca ścieżkę na podstawie bieżącego katalogu roboczego. Generalnie nie tego chcemy. Pierwszy element sys.argv list jest ścieżką głównego skryptu (uruchamianego skryptu) niezależnie od tego, czy wywołujesz listę w samym skrypcie głównym, czy w którymkolwiek z jego modułów. Może się przydać w niektórych sytuacjach. Zmienna _ _ file _ _ zawiera ścieżkę modułu, z którego została dzwoniłem.


Poniższy kod poprawnie tworzy plik example.txt w tym samym katalogu, w którym znajduje się skrypt:

filedir = os.path.dirname(os.path.realpath(__file__))
filepath = os.path.join(filedir, 'example.txt')

with open(filepath, 'w'):
    pass
 3
Author: Jeyekomon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-18 11:01:21

Z modułów pakietu Pythona musiałem odnosić się do pliku, który znajdował się w tym samym katalogu co pakiet. Ex.

some_dir/
  maincli.py
  top_package/
    __init__.py
    level_one_a/
      __init__.py
      my_lib_a.py
      level_two/
        __init__.py
        hello_world.py
    level_one_b/
      __init__.py
      my_lib_b.py

Więc w górze musiałem zadzwonić maincli.py od my_lib_a.py moduł wiedząc, że top_package i maincli.py są w tym samym katalogu. Oto jak mam drogę do maincli.py:

import sys
import os
import imp


class ConfigurationException(Exception):
    pass


# inside of my_lib_a.py
def 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')

    if not os.path.exists(maincli_path):
        err_msg = 'This script expects that "maincli.py" be installed to the '\
        'same directory: "{0}"'.format(maincli_path)
        raise ConfigurationException(err_msg)

    return maincli_path

Na podstawie postu przez PlasmaBinturong zmodyfikowałem kod.

 1
Author: Al Conrad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-12 15:09:40

Jeśli chcesz to zrobić dynamicznie w "programie" spróbuj tego kodu:
Chodzi mi o to, że możesz nie znać dokładnej nazwy modułu, aby go" zakodować". Może być wybrany z listy lub może nie być aktualnie uruchomiony, aby użyć _ _ file__.

(wiem, to nie zadział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ę "globalnego" problemu, ale znalazłem przypadki, w których nie działa Myślę, że" execfile () " można emulować w Pythonie 3 Ponieważ jest to w programie, można go łatwo umieścić w metodzie lub moduł do ponownego użycia.

 1
Author: Robin Randall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-13 19:31:39

Kiedy importujesz moduł, masz dostęp do wielu informacji. Zobacz dir(a_module). Jeśli chodzi o ścieżkę, jest do tego dunder: a_module.__path__. Możesz również po prostu wydrukować sam moduł.

>>> import a_module
>>> print(dir(a_module))
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
>>> print(a_module.__path__)
['/.../.../a_module']
>>> print(a_module)
<module 'a_module' from '/.../.../a_module/__init__.py'>
 1
Author: Y0da,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-12 08:53:23

Jeśli zainstalowałeś go za pomocą pip," PIP show " działa świetnie ('Lokalizacja')

$ pip show detectron2

Name: detectron2
Version: 0.1
Summary: Detectron2 is FAIR next-generation research platform for object detection and segmentation.
Home-page: https://github.com/facebookresearch/detectron2
Author: FAIR
Author-email: None
License: UNKNOWN
Location: /home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages
Requires: yacs, tabulate, tqdm, pydot, tensorboard, Pillow, termcolor, future, cloudpickle, matplotlib, fvcore
 0
Author: Javi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-31 13:57:45

Oto szybki skrypt bash na wypadek, gdyby był przydatny dla kogokolwiek. Chcę tylko móc ustawić zmienną środowiskową tak, że mogę pushd do kodu.

#!/bin/bash
module=${1:?"I need a module name"}

python << EOI
import $module
import os
print os.path.dirname($module.__file__)
EOI

Przykład powłoki:

[root@sri-4625-0004 ~]# export LXML=$(get_python_path.sh lxml)
[root@sri-4625-0004 ~]# echo $LXML
/usr/lib64/python2.7/site-packages/lxml
[root@sri-4625-0004 ~]#
 0
Author: shrewmouse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-10 17:51:18