문제

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

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

도움이 되었습니까?

해결책

import a_module
print(a_module.__file__)

실제로 최소한 Mac OS X에서로드 된 .pyc 파일의 경로를 제공합니다. 따라서 할 수 있다고 생각합니다.

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

당신은 또한 시도 할 수 있습니다 :

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

모듈의 디렉토리를 얻으려면

다른 팁

거기 있습니다 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. 호출 된 스크립트의 디렉토리 찾기

(이 질문들 중 일부는 그렇게 요청되었지만 여기에서 복제 된대로 폐쇄되어 리디렉션되었습니다.)

사용의 경고 __file__

가져온 모듈의 경우 :

import something
something.__file__ 

반환합니다 순수한 모듈의 경로. 그러나 FOO.PY의 FOLOWN SCRIPT :

#foo.py
print '__file__', __file__

'Python foo.py'로 호출하면 간단히 'foo.py'가 반환됩니다. Shebang을 추가하면 :

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

./foo.py를 사용하여 호출하면 './foo.py'가 반환됩니다. 다른 디렉토리에서 호출, (예 : directory bar에 foo.py를 넣음)

python bar/foo.py

또는 Shebang을 추가하고 파일을 직접 실행합니다.

bar/foo.py

'bar/foo.py'(the 상대적인 길).

디렉토리 찾기

이제 디렉토리를 얻기 위해 거기에서 가고 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 ()는 Symlinks를 해결하지 않습니다. 이 작업을 수행하려면 RealPath ()를 대신 사용하십시오. 예를 들어, symlink 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

검사 사용

@SummerBreeze는 사용을 언급합니다 검사 기준 치수.

이것은 수입 된 모듈에 대해 잘 작동하고 간결합니다.

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

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

아무도 이것에 대해 아무도 말하지 않는 이유를 알지 못하지만 가장 간단한 솔루션은 사용 중입니다. imp.find_module ( "modulename") (선적 서류 비치 여기):

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 [이름].투기 반환됩니다. 그것이 없음으로 설정되면 ValueError가 제기됩니다. 모듈이 sys.modules에 있지 않으면 sys.meta_path는 Finders에 제공된 '경로'값으로 적절한 사양을 검색합니다. 사양을 찾을 수없는 경우 리턴되지 않습니다.

이름이 하위 모듈 (DOT 포함) 인 경우 부모 모듈이 자동으로 가져옵니다.

이름 및 패키지 인수는 importLib.import_module ()과 동일합니다. 다시 말해, 상대 모듈 이름 (선행 점 포함)이 작동합니다.

이것은 사소한 일이었습니다.

각 모듈에는 a가 있습니다 __file__ 현재 위치에서 상대 경로를 보여주는 변수.

따라서 모듈에 대한 디렉토리를 얻을 수있는 디렉토리를 얻는 것은 다음과 같이 간단합니다.

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

명령 줄 유틸리티

명령 줄 유틸리티로 조정할 수 있습니다.

python-which <package name>

enter image description here


만들다 /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__)

실행 가능하게하십시오

sudo chmod +x /usr/local/bin/python-which

그래서 나는 py2exe로 이것을하려고 노력하는 데 많은 시간을 보냈다. 문제는 스크립트의 기본 폴더를 Python 스크립트로 실행했는지 또는 py2exe 실행 파일로 실행되는지 스크립트의 기본 폴더를 얻는 것이 었습니다. 또한 현재 폴더, 다른 폴더 또는 시스템 경로에서 실행되는지 여부에 관계없이 작동하도록합니다.

결국 나는 sys.frozen을 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__))
import module
print module.__path__

패키지는 하나 더 특별한 속성을 지원합니다. __path__. 이것은 패키지를 보유한 디렉토리의 이름을 포함하는 목록으로 초기화됩니다. __init__.py 해당 파일의 코드가 실행되기 전에 이 변수를 수정할 수 있습니다. 그렇게하는 것은 패키지에 포함 된 모듈 및 하위 포장에 대한 향후 검색에 영향을 미칩니다.

이 기능은 종종 필요하지 않지만 패키지에있는 모듈 세트를 확장하는 데 사용할 수 있습니다.

원천

모듈을 가져 오면 이름을 부를 수 있으며 전체 경로를 얻을 수 있습니다.

>>> import os
>>> os
<module 'os' from 'C:\\Users\\Hassan Ashraf\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\os.py'>
>>>

사용의 유일한 경고 인 경우 __file__ 현재, 상대 디렉토리가 비어있는 경우 (즉, 스크립트가있는 동일한 디렉토리에서 스크립트로 실행할 때) 사소한 솔루션은 다음과 같습니다.

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

그리고 결과 :

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

속임수가 있습니다 or '.'dirname() 전화. 그것은 dir를 다음으로 설정합니다 ., 이는 의미합니다 현재 디렉토리 모든 경로 관련 기능에 대한 유효한 디렉토리입니다.

따라서 사용 abspath() 진정으로 필요하지 않습니다. 그러나 어쨌든 사용하면 트릭이 필요하지 않습니다. abspath() 빈 경로를 허용하고 현재 디렉토리로 올바르게 해석합니다.

하나의 일반적인 시나리오 (Python 3)에 기여하고 몇 가지 접근 방식을 탐색하고 싶습니다.

내장 기능 열려 있는() 상대적 또는 절대 경로를 첫 번째 인수로 받아들입니다. 상대 경로는 다음과 같이 처리됩니다 현재 작업 디렉토리와 관련이 있습니다 그러나 파일의 절대 경로를 전달하는 것이 좋습니다.

간단히 말하면, 다음 코드로 스크립트 파일을 실행하면 ~ 아니다 그것을 보장했습니다 example.txt 파일은 스크립트 파일이있는 동일한 디렉토리에서 생성됩니다.

with open('example.txt', 'w'):
    pass

이 코드를 수정하려면 스크립트로가는 길을 가져 와서 절대적으로 만들어야합니다. 절대적인 경로를 보장하기 위해 우리는 단순히 os.path.realpath () 기능. 스크립트로가는 길을 얻으려면 다양한 경로 결과를 반환하는 몇 가지 일반적인 기능이 있습니다.

  • os.getcwd()
  • os.path.realpath('example.txt')
  • sys.argv[0]
  • __file__

두 기능 모두 os.getcwd () 그리고 os.path.realpath () 반환 경로 결과를 기반으로합니다 현재 작업 디렉토리. 일반적으로 우리가 원하는 것이 아닙니다. 첫 번째 요소 sys.argv 목록은 다음과 같습니다 루트 스크립트의 경로 루트 스크립트 자체 또는 모듈에서 목록을 호출하는지 여부에 관계없이 (실행하는 스크립트). 어떤 상황에서는 유용 할 수 있습니다. 그만큼 __파일__ 변수에는 호출 된 모듈의 경로가 포함되어 있습니다.


다음 코드는 파일을 올바르게 만듭니다 example.txt 스크립트가있는 동일한 디렉토리에서 :

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

with open(filepath, 'w'):
    pass

Python 패키지의 모듈 내에서 패키지와 동일한 디렉토리에 상주 한 파일을 참조해야했습니다. 전.

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

따라서 위에서 나는 top_package와 maincli.py가 동일한 디렉토리에 있음을 알고 my_lib_a.py 모듈에서 maincli.py를 호출해야했습니다. 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

Plasmabinturong의 게시를 기반으로 코드를 수정했습니다.

"프로그램"에서 동적 으로이 작업을 수행하려면이 코드를 사용해보십시오.
내 요점은 모듈의 정확한 이름을 "하드 코드"에 알지 못할 수도 있습니다. 목록에서 선택되었거나 현재 __file__를 사용하기 위해 실행되지 않을 수 있습니다.

(파이썬 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'>

"글로벌"문제를 제거하려고 노력했지만 작동하지 않는 경우를 발견했습니다. "execfile ()" "는 Python 3에서 모방 될 수 있다고 생각합니다. 재사용.

스크립트에서 절대 경로를 알고 싶다면 사용할 수 있습니다. 물체:

from pathlib import Path

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

cwd () 메소드

현재 디렉토리를 나타내는 새 경로 개체를 반환합니다 (OS.GetCWD ()에 의해 반환 된대로)

해결 () 메소드를 삭제합니다

경로를 절대적으로 만들어 상징 링크를 해결하십시오. 새 경로 개체가 반환됩니다.

모듈에서 패키지의 루트 경로를 검색하려면 다음 작업 (Python 3.6에서 테스트).

from . import __path__ as ROOT_PATH
print(ROOT_PATH)

메인 __init__.py 경로는 또한 사용하여 참조 할 수 있습니다 __file__ 대신에.

도움이 되었기를 바랍니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top