[python] 모듈의 경로를 검색하는 방법?

모듈이 변경되었는지 감지하고 싶습니다. 이제 inotify를 사용하는 것은 간단합니다. 알림을 받으려는 디렉토리를 알아야합니다.

파이썬에서 모듈의 경로를 어떻게 검색합니까?



답변

import a_module
print(a_module.__file__)

실제로 적어도 Mac OS X에서로드 된 .pyc 파일의 경로를 제공합니다.

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

시도해 볼 수도 있습니다 :

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

모듈의 디렉토리를 가져옵니다.


답변

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'


답변

다른 답변에서 말했듯 이이 작업을 수행하는 가장 좋은 방법은 __file__(아래에 다시 설명)입니다. 그러나 중요한 경고 __file__가 있습니다 __main__. 즉, 모듈을 자체적으로 실행하는 경우에는 존재하지 않습니다 (예 🙂 .

예를 들어, 두 개의 파일 (둘 다 PYTHONPATH에 있음)이 있다고 가정하십시오.

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

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

foo.py를 실행하면 다음과 같이 출력됩니다 :

/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

그러나 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 

도움이 되었기를 바랍니다. 이 경고는 제시된 다른 솔루션을 테스트하는 동안 많은 시간과 혼란을 초래했습니다.


답변

이 질문에 대해서도 몇 가지 변형을 시도해 보겠습니다.

  1. 호출 된 스크립트의 경로 찾기
  2. 현재 실행중인 스크립트의 경로 찾기
  3. 호출 된 스크립트의 디렉토리 찾기

(이러한 질문 중 일부는 SO에 대해 요청되었지만 중복으로 닫히고 여기로 리디렉션되었습니다.)

사용에 대한주의 사항 __file__

가져온 모듈의 경우 :

import something
something.__file__ 

모듈 의 절대 경로를 반환합니다 . 그러나 다음 스크립트 foo.py가 주어지면 :

#foo.py
print '__file__', __file__

‘python foo.py’로 호출하면 단순히 ‘foo.py’가 반환됩니다. shebang을 추가하는 경우 :

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

./foo.py를 사용하여 호출하면 ‘./foo.py’가 반환됩니다. 다른 디렉토리에서 호출 한 후 (예 : 디렉토리 표시 줄에 foo.py 입력)

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.py를 가리키는 symlink file_import_testing_link를 작성하십시오.

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

검사 사용

@SummerBreeze는 inspect를 사용하여 언급합니다. 모듈 합니다.

이것은 가져온 모듈에 대해 잘 작동하는 것으로 보이며 매우 간결합니다.

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

절대 경로를 순종적으로 반환합니다. 그러나 현재 실행중인 스크립트의 경로를 찾기 위해 스크립트를 사용하는 방법을 보지 못했습니다.


답변

아무도 이것에 대해 이야기하지 않는 이유를 알지 못하지만 가장 간단한 해결책은 imp.find_module ( “modulename”) (documentation here )을 사용하는 것입니다.

import imp
imp.find_module("os")

두 번째 위치에 경로가있는 튜플을 제공합니다.

(<open file '/usr/lib/python2.7/os.py', mode 'U' at 0x7f44528d7540>,
'/usr/lib/python2.7/os.py',
('.py', 'U', 1))

“검사”방법에 비해이 방법의 장점은 모듈을 가져 와서 작동시킬 필요가없고 입력에 문자열을 사용할 수 있다는 것입니다. 예를 들어 다른 스크립트에서 호출 된 모듈을 확인할 때 유용합니다.

편집 :

python3에서 importlib모듈은 다음을 수행해야합니다.

의 문서 importlib.util.find_spec:

지정된 모듈의 스펙을 돌려줍니다.

먼저 sys.modules를 검사하여 모듈을 이미 가져 왔는지 확인합니다. 그렇다면 sys.modules [name]입니다. 투기 이 반환됩니다. 이것이 None으로 설정되면 ValueError가 발생합니다. 모듈이 sys.modules에 없으면 sys.meta_path는 파인더에 제공된 ‘path’값을 가진 적합한 스펙을 검색합니다. 스펙을 찾을 수 없으면 아무것도 리턴되지 않습니다.

하위 모듈의 이름 인 경우 (점 포함) 상위 모듈을 자동으로 가져옵니다.

이름 및 패키지 인수는 importlib.import_module ()과 동일하게 작동합니다. 다시 말해, 상대 모듈 이름 (점으로 표시)이 작동합니다.


답변

이것은 사소한 것이었다.

각 모듈에는 __file__현재 위치의 상대 경로를 나타내는 변수가 있습니다.

따라서 모듈이이를 알리기위한 디렉토리를 얻는 것은 다음과 같이 간단합니다.

os.path.dirname(__file__)


답변

import os
path = os.path.abspath(__file__)
dir_path = os.path.dirname(path)