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


482

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

예를 들어 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()하면 현재 파일이 아닌 원래 시작 스크립트의 파일 경로가 반환됩니다.)



2
os.path.realpath ( file )
Girish Gupta

답변:


256

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

11
주의 :이 호출은 다른 환경에서 동일한 결과를 제공하지 않습니다. : 아래 우사기의 답변을 받아 고려 stackoverflow.com/a/6628348/851398
패러데이

3
@faraday : 예를 들어 주시겠습니까? 나는 비슷한 질문을 사용하여inspect.getabsfile() 대답 했으며 시도한 모든 경우에 효과적이었습니다.
jfs

1
실제로 @Usagi가 더 나은 답변입니까?
Dror

4
아니 그것을 훨씬 더 못을 박았다 user13993
osirisgothra

6
user13993은 실제로 그것을 못 박았습니다. 이어야한다os.path.realpath(__file__)
uchuugaka

566
__file__

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

import os

os.path.realpath(__file__)

14
때로는 __file__'script_name.py'를 반환하고 다른 경우에는 'script_name.pyc'를 반환 하기 때문에이 방법에주의해야합니다 . 따라서 출력이 안정적이지 않습니다.
mechatroner

27
그러나 우리는 관련이없는이 파일의 경로 만 사용하기 때문에.
Uwe Koloska

5
"__file__"따옴표 (문자열)로 명령 행 에서 실행할 때 cmd가 실행되는 dir을 제공하지만 __file__ 따옴표없이 소스 파일에 대한 경로를 제공합니다 ... 이유는 무엇입니까?
muon

7
@muon 전달 된 파일 이름 문자열이 존재하는지 여부에 대한 검사는 수행되지 않으며 파일 경로는 cwd를 기준으로하므로 os.path.realpath함수는 dir경로 의 일부를 가정합니다 . os.path.dirname(os.path.realpath(__file__))파일과 함께 디렉토리를 반환합니다. os.path.dirname(os.path.realpath("__file__"))cwd를 반환합니다. os.path.dirname(os.path.realpath("here_be_dragons"))또한 cwd를 반환합니다.
Jamie Bull

86

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

72

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

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

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

print inspect.getfile(inspect.currentframe())

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

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

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


4
튜플 내부의 위치에 의존하지 않는 것이 좋습니다. 코드를 읽을 때 어떤 데이터를 얻으려고하는지 명확하지 않습니다.
jpmc26

5
inspect.getfile()__file__모듈 객체를 전달한 경우 속성을 반환 합니다. inspect.currentframe()모듈을 반환합니다. 에르고, 이것은 비싼 말입니다 __file__.
Martijn Pieters

inspect.stack()는 단순한 것보다 훨씬 비싼 함수이며 모듈 객체를 inspect.currentframe()호출 inspect.getfile()합니다.
Martijn Pieters

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

1
방금 @Pat Notz의 의견을 시도했습니다. 파일 이름을 통해 얻을 수 있다고 생각합니다 __file__.
hlin117

Python3에서는 os.path.dirname스크립트를 실행하는 상대 경로를 제공합니다. 의 예를 들어 python ../../test.pyos.path.dirname될 것입니다 ../../및 스크립트에없는 절대 경로. 나는 경로를 찾고 있었지만 스크립트의 이름을 제거했습니다. sys.path의 첫 번째 요소는 분명히 답 sys.path[0]입니다.
aerijman

37

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

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

그것은 일식에 대한 단위 테스트를 잘하지만 작동, 나는 /home/user/Softwares/eclipse/plugins/org.python.pydev_4.5.5.201603221110/pysrc 있어요
hayj

2
이 방법은 비용이 많이 드는 철자법 sys.modules['__main__'].__file__입니다.
Martijn Pieters

14
import os
print os.path.basename(__file__)

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


14

"현재 프로세스 내에서 실행중인 파일의 파일 경로"가 무엇을 의미하는지 완전히 명확하지는 않습니다. sys.argv[0]일반적으로 Python 인터프리터가 호출 한 스크립트의 위치를 ​​포함합니다. 자세한 내용 은 sys 설명서 를 확인하십시오.

@Tim과 @Pat Notz가 지적했듯이 __file__ 속성은

모듈이 파일에서로드 된 경우 모듈이로드 된 파일


1
python 프로그램을 win32 exe로 전달하면 "print os.path.abspath ( file )"및 "print inspect.getfile (inspect.currentframe ())"이 작동하지 않습니다. sys.argv [0] 만 작동합니다! :) 그러나 당신은 단지 이름을 얻는다!
aF.

11

Windows 환경에서 작동 해야하는 스크립트가 있습니다. 이 코드는 내가 완료 한 것입니다.

import os,sys
PROJECT_PATH = os.path.abspath(os.path.split(sys.argv[0])[0])

꽤 해키 결정입니다. 그러나 외부 라이브러리가 필요하지 않으며 제 경우에는 가장 중요합니다.


1
나는 이것을 위해 "os, sys"를 가져와야했지만 지금까지는 문자열 끝에 파일 이름이없는 경로 만 실제로 반환하는 것이 가장 좋은 대답이다.
emmagras

10

이 시도,

import os
os.path.dirname(os.path.realpath(__file__))

8
import os
os.path.dirname(os.path.abspath(__file__))

검사 또는 다른 라이브러리가 필요하지 않습니다.

가져온 스크립트와 동일한 폴더에있는 구성 파일을 사용하는 스크립트를 다른 디렉토리에서 실행 한 스크립트에서 가져와야 할 때 나에게 도움이되었습니다.


현재 작업 디렉토리 (os.getcwd)가 파일이있는 디렉토리와 다른 경우 원하는 응답을 생성하지 않습니다.
Iron Pillow

2
어떻게 요? 이 경우 나에게 잘 작동합니다. 파일이있는 디렉토리를 얻습니다.
Michael Mior

@IronPillow 아마도이 답변은 필요한 것에 도움이 될 것입니다. stackoverflow.com/a/41546830/3123191
Kwuite


6
import sys

print sys.path[0]

이것은 현재 실행중인 스크립트의 경로를 인쇄합니다


2
sys.path [0]은 매우 유용하지만 요청 된대로 script3이 아닌 script1의 경로를 제공합니다.
James

적어도 OS X에서 2.7을 사용하면 이것이 신뢰할만한 것을 찾지 못합니다. 동일한 파일을 직접 실행하면 작동합니다. repl에서, 특히 수입 계란에서 작동하지 않습니다
uchuugaka

5

난 그냥 생각 __file__ 당신은 또한 체크 아웃 할 수 있습니다처럼 사운드를 모듈을 검사합니다 .


아아 ... execfile은 까다 롭다. inspect 모듈 사용에 대한 다른 게시물을 참조하십시오.
Pat Notz

4

당신이 사용할 수있는 inspect.stack()

import inspect,os
inspect.stack()[0]  => (<frame object at 0x00AC2AC0>, 'g:\\Python\\Test\\_GetCurrentProgram.py', 15, '<module>', ['print inspect.stack()[0]\n'], 0)
os.path.abspath (inspect.stack()[0][1]) => 'g:\\Python\\Test\\_GetCurrentProgram.py'

4

Python 3은 상당히 주류이므로 pathlib파일 및 경로 정보에 액세스하는 데 더 나은 도구라고 생각 하므로 답변 을 포함하고 싶었습니다 .

from pathlib import Path

current_file: Path = Path(__file__).resolve()

현재 파일의 디렉토리를 찾고 있다면 명령문에 추가 .parent하는 것만 큼 ​​쉽습니다 Path().

current_path: Path = Path(__file__).parent.resolve()

3
import sys
print sys.argv[0]

10
불행히도 이것은 스크립트가 전체 경로로 호출 된 경우에만 작동합니다. 스크립트에 대한 호출 인 명령 행에서 "첫 번째 인수"만 리턴하기 때문입니다.
cregox

2

이것은 작동해야합니다 :

import os,sys
filename=os.path.basename(os.path.realpath(sys.argv[0]))
dirname=os.path.dirname(os.path.realpath(sys.argv[0]))

2
print(__file__)
print(__import__("pathlib").Path(__file__).parent)

4
코드 만 답변하지 않는 것이 좋습니다. 이것이 어떻게 문제를 해결하는지 또는 이것이 기존 답변과 어떻게 다른지에 대한 설명을 추가하십시오. 검토에서
Nick

1

스크립트를 실행하는 디렉토리를 얻으려면

 print os.path.dirname( inspect.getfile(inspect.currentframe()))

1

나는 항상 현재 작업 디렉토리 (CWD)의 os 기능을 사용했습니다. 이것은 표준 라이브러리의 일부이며 구현하기가 매우 쉽습니다. 예를 들면 다음과 같습니다.

    import os
    base_directory = os.getcwd()

1
제기 된 질문에 적용되도록 답변을 수정할 수 있습니까? 이 답변은 " 현재 실행중인 파일 의 경로와 이름 어떻게 얻 습니까? " 라는 질문에는 적용되지 않습니다.
Marco

1
이것은 python 명령을 실행 한 경로를 제공합니다. 따라서 python script.py이미 존재하는 동일한 폴더에서 명령 을 실행할 때 작동하는 것처럼 보이지만 실제로 pwd는 Linux에서 실행하는 것과 같습니다 .
George

0

나는 __FILE__과 접근 방식을 사용
os.path.abspath(__file__)
하지만, 코드가 처음 실행될 때 약간의 트릭이는 평 파일을 반환, 다음 실행이 * 된 .pyc 파일의 이름을이
내가 함께 머물 수 있도록 :
inspect.getfile(inspect.currentframe())
또는
sys._getframe().f_code.co_filename


0

이클립스 디버거unittest 를 고려한 함수를 작성했습니다 . 처음 실행 한 스크립트의 폴더를 반환합니다. 선택적으로 __file__ var를 지정할 수 있지만 가장 중요한 것은 모든 호출 계층 에서이 변수를 공유 할 필요가 없다는 것입니다 .

어쩌면 당신은 다른 사람들이 내가 보지 못한 특정 사례를 쌓을 수는 있지만 나에게는 괜찮습니다.

import inspect, os
def getRootDirectory(_file_=None):
    """
    Get the directory of the root execution file
    Can help: http://stackoverflow.com/questions/50499/how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executing
    For eclipse user with unittest or debugger, the function search for the correct folder in the stack
    You can pass __file__ (with 4 underscores) if you want the caller directory
    """
    # If we don't have the __file__ :
    if _file_ is None:
        # We get the last :
        rootFile = inspect.stack()[-1][1]
        folder = os.path.abspath(rootFile)
        # If we use unittest :
        if ("/pysrc" in folder) & ("org.python.pydev" in folder):
            previous = None
            # We search from left to right the case.py :
            for el in inspect.stack():
                currentFile = os.path.abspath(el[1])
                if ("unittest/case.py" in currentFile) | ("org.python.pydev" in currentFile):
                    break
                previous = currentFile
            folder = previous
        # We return the folder :
        return os.path.dirname(folder)
    else:
        # We return the folder according to specified __file__ :
        return os.path.dirname(os.path.realpath(_file_))

0

플랫폼 (macOS / Windows / Linux)에서 마이그레이션 일관성을 유지하려면 다음을 시도하십시오.

path = r'%s' % os.getcwd().replace('\\','/')


2
이것은 잘못이다. 현재 파일의 경로가 아닌 현재 경로를 가져옵니다.
Charles Plager

0

가장 간단한 방법은 다음과 같습니다.

script_1.py :

import subprocess
subprocess.call(['python3',<path_to_script_2.py>])

script_2.py :

sys.argv[0]

추신 : 나는 시도 execfile했지만 script_2.py를 문자열로 읽었으므로을 sys.argv[0]반환했습니다 <string>.


0

다음은 내가 사용하는 것이므로 문제없이 어디서나 코드를 던질 수 있습니다. __name__은 항상 정의되지만 __file__코드가 파일로 실행될 때만 정의됩니다 (예 : IDLE / iPython에서는).

    if '__file__' in globals():
        self_name = globals()['__file__']
    elif '__file__' in locals():
        self_name = locals()['__file__']
    else:
        self_name = __name__

또는 다음과 같이 작성할 수 있습니다.

self_name = globals().get('__file__', locals().get('__file__', __name__))

-2

이 답변의 대부분은 Python 버전 2.x 이하에서 작성되었습니다. Python 3.x에서 print 함수의 구문은 괄호 (예 : print ())를 요구하도록 변경되었습니다.

따라서 Python 2.x에서 user13993의 초기 고득점 답변 :

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

Python 3.x에서 사용 :

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

-3

당신이없는 파일 이름 만 원 ./하거나 .py이것을 시도 할 수 있다면

filename = testscript.py
file_name = __file__[2:-3]

file_name [] 안의 색인을 변경하여 원하는 것을 생성 할 수있는 테스트 스크립트를 인쇄합니다.


-3
import os

import wx


# return the full path of this file
print(os.getcwd())

icon = wx.Icon(os.getcwd() + '/img/image.png', wx.BITMAP_TYPE_PNG, 16, 16)

# put the icon on the frame
self.SetIcon(icon)

7
os.getcwd ()는 현재 실행중인 파일의 디렉토리가 아닌 PROCESS의 현재 WORKING 디렉토리를 리턴합니다. 이것은 올바른 결과를 반환하는 것처럼 보이지만 결과가 현재 파일의 상위 디렉토리가 아닌 경우가 많이 있습니다. 위에서 제안한 것처럼 os.path.dirname ( file ) 을 사용하는 것이 훨씬 좋습니다 .
samaspin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.