Вопрос-Ответ

How to retrieve a module's path?

Как получить путь к модулю?

Я хочу определить, изменился ли модуль. Теперь использовать inotify просто, вам просто нужно знать каталог, из которого вы хотите получать уведомления.

Как мне получить путь к модулю в python?

Переведено автоматически
Ответ 1
import a_module
print(a_module.__file__)

Фактически предоставит вам путь к файлу .pyc, который был загружен, по крайней мере, в Mac OS X. Так что, я думаю, вы можете сделать:

import os
path = os.path.abspath(a_module.__file__)

Вы также можете попробовать:

path = os.path.dirname(a_module.__file__)

Чтобы получить каталог модуля.

Ответ 2

В python есть inspect модуль.

Официальная документация


Модуль inspect предоставляет несколько полезных функций, помогающих получать информацию о живых объектах, таких как модули, классы, методы, функции, обратные трассировки, объекты фрейма и объекты кода. Например, он может помочь вам изучить содержимое класса, получить исходный код метода, извлечь и отформатировать список аргументов для функции или получить всю информацию, необходимую для отображения подробной обратной трассировки.


Пример:

>>> 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'
Ответ 3

Как говорилось в других ответах, лучший способ сделать это с помощью __file__ (снова продемонстрировано ниже). Однако есть важный нюанс, который заключается в том, что __file__ не существует, если вы запускаете модуль сам по себе (т. Е. Как __main__).

Допустим, у вас есть два файла (оба находятся в вашем PYTHONPATH):

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

и

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

Запуск foo.py выдаст результат:

/path3        # "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

ОДНАКО, если вы попытаетесь запустить bar.py самостоятельно, вы получите:

/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

Надеюсь, это поможет. Это предостережение стоило мне много времени и путаницы при тестировании других представленных решений.

Ответ 4

I will try tackling a few variations on this question as well:


  1. finding the path of the called script

  2. finding the path of the currently executing script

  3. finding the directory of the called script

(Some of these questions have been asked on SO, but have been closed as duplicates and redirected here.)

Caveats of Using __file__

For a module that you have imported:

import something
something.__file__

will return the absolute path of the module. However, given the folowing script foo.py:

#foo.py
print '__file__', __file__

Calling it with 'python foo.py' Will return simply 'foo.py'. If you add a shebang:

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

and call it using ./foo.py, it will return './foo.py'. Calling it from a different directory, (eg put foo.py in directory bar), then calling either

python bar/foo.py

или добавить shebang и выполнить файл напрямую:

bar/foo.py

вернет 'bar/foo.py' (относительный путь).

Поиск каталога

Теперь перейти оттуда, чтобы получить каталог, os.path.dirname(__file__) также может быть непросто. По крайней мере, в моей системе он возвращает пустую строку, если вы вызываете его из того же каталога, что и файл. например.

# foo.py
import os
print '__file__ is:', __file__
print 'os.path.dirname(__file__) is:', os.path.dirname(__file__)

выведет:

__file__ is: foo.py
os.path.dirname(__file__) is:

Другими словами, он возвращает пустую строку, поэтому это не кажется надежным, если вы хотите использовать ее для текущего файла (в отличие от файла импортированного модуля). Чтобы обойти это, вы можете обернуть это в вызов abspath:

# 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__))

который выводит что-то вроде:

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

Обратите внимание, что abspath() НЕ разрешает символьные ссылки. Если вы хотите это сделать, используйте вместо этого realpath() . Например, создание символьной ссылки file_import_testing_link, указывающей на file_import_testing.py, со следующим содержимым:

import os
print 'abspath(__file__)',os.path.abspath(__file__)
print 'realpath(__file__)',os.path.realpath(__file__)

выполнение выведет абсолютные пути примерно так:

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

file_import_testing_link -> file_import_testing.py

Использование inspect

@SummerBreeze упоминает использование модуля inspect.

Кажется, это работает хорошо и довольно лаконично для импортированных модулей:

import os
import inspect
print 'inspect.getfile(os) is:', inspect.getfile(os)

послушно возвращает абсолютный путь. Для нахождения пути к текущему исполняемому скрипту:

inspect.getfile(inspect.currentframe())

(спасибо @jbochi)

inspect.getabsfile(inspect.currentframe()) 

указывает абсолютный путь к текущему исполняемому скрипту (спасибо @Sadman_Sakib).

python