[python] 현재 실행중인 파일의 경로와 이름은 어떻게 얻습니까?

다른 스크립트 파일을 호출하는 스크립트가 있지만 현재 프로세스 내에서 실행중인 파일의 파일 경로를 가져와야합니다.

예를 들어 3 개의 파일이 있다고 가정 해 봅시다. execfile 사용 :

  • script_1.py전화 script_2.py.
  • 차례로을 script_2.py호출합니다 script_3.py.

어떻게 파일 이름과 경로 얻을 수있는 script_3.py, 내 코드에서를script_3.py 에서 인수로 그 정보를 전달하지 않고 script_2.py?

(실행 os.getcwd()하면 현재 파일이 아닌 원래 시작 스크립트의 파일 경로가 반환됩니다.)



답변

p1.py :

execfile("p2.py")

p2.py :

import inspect, os
print (inspect.getfile(inspect.currentframe()) # script filename (usually with path)
print (os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))) # script directory


답변

__file__

다른 사람들이 말했듯이. os.path.realpath 를 사용 하여 심볼릭 링크를 제거 할 수도 있습니다 .

import os

os.path.realpath(__file__)


답변

2018-11-28 업데이트 :

다음은 Python 2 및 3 실험에 대한 요약입니다.

main.py는 – foo.py 실행
foo.py을 – 실행 lib 디렉토리 / bar.py
lib 디렉토리 / bar.py – 인쇄는 표현을 파일 경로

| Python | Run statement       | Filepath expression                    |
|--------+---------------------+----------------------------------------|
|      2 | execfile            | os.path.abspath(inspect.stack()[0][1]) |
|      2 | from lib import bar | __file__                               |
|      3 | exec                | (wasn't able to obtain it)             |
|      3 | import lib.bar      | __file__                               |

Python 2의 경우 패키지로 전환하는 것이 더 명확 할 수 있으므로 두 개의 폴더에 from lib import bar__init__.py파일을 추가 하기 만하면 됩니다.

Python 3의 경우 execfile존재하지 않습니다. 가장 가까운 대안은 exec(open(<filename>).read())스택 프레임에 영향을 미치지 만입니다. 그것은 단순한 그냥 사용하지하는의 import fooimport lib.bar더 – __init__.py필요한 파일을.

import와 execfile의 차이점 도 참조하십시오.


원래 답변 :

다음은이 스레드의 답변을 기반으로 한 실험입니다-Windows의 Python 2.7.10.

스택 기반은 신뢰할 수있는 결과를 제공하는 것으로 보입니다. 마지막 두 구문은 가장 짧은 구문입니다 .

print os.path.abspath(inspect.stack()[0][1])                   # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1]))  # C:\filepaths\lib

이것들은 sys 에 함수 로 추가 되는 것입니다! @Usagi와 @pablog의 신용

다음 세 파일을 기반으로 폴더에서 main.py를 실행하여 python main.py(절대 경로가있는 execfile을 시도하고 별도의 폴더에서 호출).

C : \ filepaths \ main.py : execfile('foo.py')
C : \ filepaths \ foo.py : execfile('lib/bar.py')
C : \ filepaths \ lib \ bar.py :

import sys
import os
import inspect

print "Python " + sys.version
print

print __file__                                        # main.py
print sys.argv[0]                                     # main.py
print inspect.stack()[0][1]                           # lib/bar.py
print sys.path[0]                                     # C:\filepaths
print

print os.path.realpath(__file__)                      # C:\filepaths\main.py
print os.path.abspath(__file__)                       # C:\filepaths\main.py
print os.path.basename(__file__)                      # main.py
print os.path.basename(os.path.realpath(sys.argv[0])) # main.py
print

print sys.path[0]                                     # C:\filepaths
print os.path.abspath(os.path.split(sys.argv[0])[0])  # C:\filepaths
print os.path.dirname(os.path.abspath(__file__))      # C:\filepaths
print os.path.dirname(os.path.realpath(sys.argv[0]))  # C:\filepaths
print os.path.dirname(__file__)                       # (empty string)
print

print inspect.getfile(inspect.currentframe())         # lib/bar.py

print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\filepaths\lib
print

print os.path.abspath(inspect.stack()[0][1])          # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1]))  # C:\filepaths\lib
print


답변

나는 이것이 더 깨끗하다고 ​​생각합니다.

import inspect
print inspect.stack()[0][1]

다음과 같은 정보를 얻습니다.

print inspect.getfile(inspect.currentframe())

[0]이 스택의 현재 프레임 (스택 상단)이고 [1]이 파일 이름을 나타내는 경우 스택에서 뒤로 증가하도록 증가합니다.

print inspect.stack()[1][1]

현재 프레임을 호출 한 스크립트의 파일 이름입니다. 또한 [-1]을 사용하면 원래 호출 스크립트 인 스택의 맨 아래로 이동합니다.


답변

import os
os.path.dirname(__file__) # relative directory path
os.path.abspath(__file__) # absolute file path
os.path.basename(__file__) # the file name only


답변

스크립트가 하나의 파일로만 구성된 경우 최상의 것으로 표시된 제안은 모두 사실입니다.

모듈로 가져올 수있는 파일에서 실행 파일 이름 (예 : 현재 프로그램의 파이썬 인터프리터에 전달 된 루트 파일)을 찾으려면이를 수행해야합니다 (파일에 있다고 가정합니다) 이름이 foo.py ) :

import inspect

print inspect.stack()[-1][1]

[-1]스택 의 마지막 항목 ( )이 스택에 들어간 첫 번째 항목이므로 (스택은 LIFO / FILO 데이터 구조입니다).

그런 다음 bar.py 파일에서 foo.py 대신 bar.py를import foo 인쇄 하면 다음과 같은 값이됩니다.

  • __file__
  • inspect.getfile(inspect.currentframe())
  • inspect.stack()[0][1]

답변

import os
print os.path.basename(__file__)

파일 이름 만 알려줍니다. 즉, 파일의 경로가 c : \ abcd \ abc.py이면 두 번째 줄은 abc.py를 인쇄합니다