__file__ in Application by PyInstaller

오픈소스·2021년 3월 18일
0
post-thumbnail

main.py

import os
import sub

def print_file():
    print(os.path.abspath(__file__))

if __name__ == '__main__':
    print_file()
    sub.print_file()

sub.py

import os

def print_file():
    print(os.path.abspath(__file__))

Run python script on run-time

$ python main.py 
/Users/youngkiu/src/underscore_file_test/main.py
/Users/youngkiu/src/underscore_file_test/sub.py

Build python script using PyInstaller

$ pyinstaller --onefile main.py

Run executable file built by PyInstaller

$ cd dist
$ ./main 
/Users/youngkiu/src/underscore_file_test/dist/main.py
/var/folders/18/fn9x6gxn7g17gl7vby9cj5gc0000gn/T/_MEIGGEXQN/sub.pyc

결론

__file__ Special Variable을 이용해, 코드의 디렉토리 경로를 구하는데 사용하는데,
ex) BASE_DIR = os.path.dirname(os.path.abspath(__file__))
PyInstaller에 의해 만들어진 실행화일 때,

  • __file__가 entry script에서는 executable 화일 위치
  • __file__가 entry script가 아닌 화일에서는 Local App Data Temp 디렉토리 내의 위치

같은 디렉토리의 한 프로그램에서 서로 다른 경로를 가지게 되어, 이를 주의해야 합니다.

추천

PyInstaller 사용시에는 __file__를 사용하지 말고,

if getattr(sys, 'frozen', False):
    APPLICATION_EXE_DIR = os.path.dirname(sys.executable)
    APPLICATION_DATA_DIR = sys._MEIPASS
else:
    APPLICATION_EXE_DIR = os.path.dirname(os.path.abspath(__file__))
    APPLICATION_DATA_DIR = APPLICATION_EXE_DIR

명시적으로 sys.executablesys._MEIPASS의 사용을 추천합니다.

1개의 댓글

comment-user-thumbnail
2022년 8월 30일

감사합니다.^_^

답글 달기