Programming

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

procodes 2020. 2. 15. 23:36
반응형

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


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

예를 들어 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(절대 경로가있는 exec 파일을 시도하고 별도의 폴더에서 호출).

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를 인쇄합니다


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

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

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


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

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

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


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

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

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


__file__속성은 기본 실행 코드가 포함 된 파일과 가져온 모듈 모두에서 작동합니다.

참조 https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file__를


이 시도,

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

import sys

print sys.path[0]

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


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


당신이 사용할 수있는 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'

import sys
print sys.argv[0]

이것은 작동해야합니다 :

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

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

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

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

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


이클립스 디버거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_))

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

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


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

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>.


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

    import os
    base_directory = os.getcwd()

다음은 내가 사용하는 것이므로 문제없이 어디서나 코드를 던질 수 있습니다. __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__))

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

from pathlib import Path

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

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

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

이 답변의 대부분은 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

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

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

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


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)

참고 URL : https://stackoverflow.com/questions/50499/how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executing



반응형