답변:
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__)
모듈의 디렉토리를 가져옵니다.
__file__
은 아닙니다 ( 실행중인 스크립트의 경우 전체 경로가 아니며 상대 경로입니다). 내가있는 파일의 경우 동일한 디렉토리에서 다른 모듈을 가져 와서 여기에 표시된대로 수행해야했습니다. 누구나 더 편리한 방법을 알고 있습니까?
self.__file__
os.path.dirname(__file__)
는 저에게 잘 작동하며 모듈 디렉토리의 abs 경로를 반환합니다.
AttributeError: 'module' object has no attribute '__file__'
path = module.__path__.__dict__["_path"][0]
지만, 이식 가능한지 또는 파이썬 버전 사이에 다른지 확실하지 않습니다. 그것은 같은 오류와 inspect
답변을 올리는 이 답변과 달리 나를 위해 일하고 있습니다 TypeError: <module 'module' (namespace)> is a built-in module
...
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'
inspect.currentframe()
inspect.getfile()
접근 방식은 모듈 _io
에서는 작동하지 않지만 모듈 에서는 작동합니다 io
.
다른 답변에서 말했듯 이이 작업을 수행하는 가장 좋은 방법은 __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
도움이 되었기를 바랍니다. 이 경고는 제시된 다른 솔루션을 테스트하는 동안 많은 시간과 혼란을 초래했습니다.
__file__
` __file__
NameError
습니까? @ 폴 뒤 부아 : 나는 파이썬 2.3-3.4 시도하고 __file__
그러나 내가 파이썬 파일을 실행 정의된다 : python a.py
, python -ma
, ./a.py
.
이 질문에 대해서도 몇 가지 변형을 시도해 보겠습니다.
(이러한 질문 중 일부는 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)
절대 경로를 순종적으로 반환합니다. 그러나 현재 실행중인 스크립트의 경로를 찾기 위해 스크립트를 사용하는 방법을 보지 못했습니다.
inspect.getfile(inspect.currentframe())
현재 실행중인 스크립트의 경로를 얻는 데 사용할 수 있습니다 .
아무도 이것에 대해 이야기하지 않는 이유를 알지 못하지만 가장 간단한 해결책은 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 ()과 동일하게 작동합니다. 다시 말해, 상대 모듈 이름 (점으로 표시)이 작동합니다.
importlib.machinery.PathFinder().find_module("os").get_filename()
imp.find_module
Python3 +에서 찾은 가장 짧은 대안 . 누구든지의 사용법을 찾고 있다면 importlib.util.find_spec
.
이것은 사소한 것이었다.
각 모듈에는 __file__
현재 위치의 상대 경로를 나타내는 변수가 있습니다.
따라서 모듈이이를 알리기위한 디렉토리를 얻는 것은 다음과 같이 간단합니다.
os.path.dirname(__file__)
import module
print module.__path__
패키지는 하나 이상의 특수 속성을 지원합니다
__path__
. 이것은__init__.py
해당 파일의 코드가 실행되기 전에 패키지를 보유한 디렉토리의 이름을 포함하는 목록으로 초기화됩니다 . 이 변수는 수정할 수 있습니다. 이렇게하면 패키지에 포함 된 모듈 및 하위 패키지에 대한 향후 검색에 영향을줍니다.이 기능은 종종 필요하지는 않지만 패키지에있는 모듈 세트를 확장하는 데 사용할 수 있습니다.
명령 줄 유틸리티로 조정할 수 있습니다.
python-which <package name>
창조하다 /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 로이 작업을 수행하는 데 상당한 시간을 보냈습니다. 파이썬 스크립트 또는 py2exe 실행 파일로 실행 중인지 스크립트의 기본 폴더를 얻는 것이 문제였습니다. 또한 현재 폴더, 다른 폴더에서 실행되었는지 또는 시스템 경로에서 (가장 어려웠는지) 작동하는지 확인하십시오.
결국 나는 py2exe에서 실행 표시기로 sys.frozen을 사용 하여이 접근법을 사용했습니다.
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__))
사용상의 유일한 경고 __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()
빈 경로를 허용하고 현재 디렉토리로 올바르게 해석합니다.
os.path.dirname(os.path.abspath(__file__))
상대 경로에 대해 전혀 걱정할 필요가 없으므로 순서를 바꾸고 사용하는 것이 좋습니다. 버그에 대한 기회가 적습니다.
하나의 일반적인 시나리오 (Python 3)에 기여하고 이에 대한 몇 가지 접근법을 탐색하고 싶습니다.
내장 함수 open () 은 상대 또는 절대 경로를 첫 번째 인수로 허용합니다. 상대 경로는 현재 작업 디렉토리에 상대적인 것으로 취급 되므로 파일에 절대 경로를 전달하는 것이 좋습니다.
단순히 당신이 다음 코드를 사용하여 스크립트 파일을 실행하는 경우가있다 고 말했다 하지 보장 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 목록 의 첫 번째 요소 는 루트 스크립트 자체 또는 해당 모듈에서 목록을 호출하는지 여부에 관계없이 루트 스크립트 (실행하는 스크립트 )의 경로입니다 . 상황에 따라 편리 할 수 있습니다. __file__의 변수는 호출 된 모듈로부터의 경로를 포함한다.
다음 코드 example.txt
는 스크립트가있는 동일한 디렉토리에 파일 을 올바르게 작성합니다 .
filedir = os.path.dirname(os.path.realpath(__file__))
filepath = os.path.join(filedir, 'example.txt')
with open(filepath, 'w'):
pass
스크립트에서 절대 경로를 알고 싶다면 Path 객체를 사용할 수 있습니다 .
from pathlib import Path
print(Path().absolute())
print(Path().resolve('.'))
print(Path().cwd())
os.getcwd ()에 의해 반환 된 현재 디렉토리를 나타내는 새로운 경로 객체를 반환
심볼릭 링크를 해결하여 경로를 절대적으로 만듭니다. 새로운 경로 객체가 반환됩니다.
파이썬 패키지의 모듈 내에서 패키지와 동일한 디렉토리에있는 파일을 참조해야했습니다. 전의.
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에서 에뮬레이트 될 수 있다고 생각합니다. 이것은 프로그램에 있기 때문에 쉽게 메소드 또는 모듈에 넣을 수 있습니다 재사용.
pip를 사용하여 설치 한 경우 "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
다음은 누구에게나 유용한 bash 스크립트입니다. pushd
코드에 할 수 있도록 환경 변수를 설정할 수 있기를 원합니다 .
#!/bin/bash
module=${1:?"I need a module name"}
python << EOI
import $module
import os
print os.path.dirname($module.__file__)
EOI
셸 예제 :
[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 ~]#