티스토리 뷰
[파이썬] cx_freeze pyinstaller 실행 파일 배포 .exe 만들기: on console 'NoneType' object has no attribute write error 해결 방법
JC story 2023. 4. 12. 22:55안녕하세요 종백이입니다😎
오늘은 파이썬 .py 스크립트를 누구나 사용할 수 있게 .exe 만드는 방법을 알아보려고 합니다!
실행파일 배포 대표적인 2가지 모듈
1. pyinstaller
2. cx_freeze
위 두 모듈을 이용해서 main.py 를 .exe 파일로 배포하는 것을 알아보겠습니다😎
1. pyinstaller
설치 방법
pip install pyinstaller
사용방법
기본 배포
pyinstaller main.py
한 파일로 배포(-F or --onfile)
pyinstaller -F main.py
한 폴더로 배포(-D or --onedir)
pyinstaller -D main.py
배포시 .exe 아이콘 변경
pyinstaller --icon="iconPath/iconfile.ico" main.py
이름 변경
pyinstaller --name test.exe main.py
no console
pyinstaller --noconsole main.py
위 옵션을 섞고 싶을 땐 띄어쓰기로 여러 옵션을 추가해서 사용하시면 됩니다! 예를 들어 한파일로 배포하고 노콘솔로 하고 싶으시면
pyinstaller -F --noconsole main.py
위와 같은 방식으로 하시면 됩니다😎
가끔 pyinstaller로 배포파일을 만들었을 때 이유 모를 오류가 있는데 이럴 때 cx_freeze를 사용하면 오류 없이 실행되는 경우가 있어서 cx_freeze도 같이 사용합니다!
2. cx_freeze
설치방법
pip install cx_freeze
사용방법
cx_freeze는 main.py 스크립트와 동일한 폴더에 setup.py를 구성해야 합니다.
setup.py
from cx_Freeze import setup, Executable
buildOptions = {
"packages":[
'requests','time','zipfile','shutil','os','win32gui', 'win32con', 'subprocess'
],
"excludes":[
"tkinter","matplotlib"
]
}
exe = [Executable('main.py', base='Win32GUI')]
setup(
name='main',
version='1.0',
author='me',
options = dict(build_exe = buildOptions),
executables = exe
)
위와 같이 setup.py를 구성하면 됩니다.
설명을 드리자면 buildOptions "packages" 부분에는 사용하는 패키지를 넣어주시면 됩니다! 그리고 "excludes" 부분에는 사용하지 않는 패키지를 넣어주시면 됩니다!
여기서 사용하지 않는 패키지를 넣는 이유는 buildOptions 부분 없이 돌리면 cx_freeze 가 대충 모듈 다 다운로드하기 때문에 용량이 커지는데 여기서 buildOptions을 통해 필요한 패키지만 넣어주기 위해서 buildOptions을 사용합니다 ㅎㅎ
exe 부분은 실행할 스크립트를 넣어주시면 됩니다! 여기서 base="Win32GUI"를 보실 수 있는데요 이 부분은 pyinstaller에서 noconsole 옵션과 똑같습니다. 콘솔을 띄우실 분들은 base부분을 제외하시고 exe=[Executable('main.py')] 만 쓰시면 됩니다!
setup부분에는 필요한 내용을 넣으시고 setup.py 가 완료되었다면 해당 폴더 cmd 창에서 해당 폴더 path에 들어가셔서
python setup.py build
를 외치면 됩니다!
no console 에러
'NoneType' object has no attribute write error
pyinstaller나 cx_freeze 사용 시 GUI를 따로 구성하신 분들은 noconsole 옵션을 많이 사용하시는데요? 여기서 자주 에러가 발생합니다!
그 이유는 콘솔에 로그를 찍는 모듈이 포함되어 있을 때 콘솔이 없으면 로그를 기록할 위치가 없어서 에러가 발생하기 때문인데요!
이럴 경우에는 고인 물천국인 스택오버플로우에서 해결방법을 알려주었습니다!
우리의 해결사 스택오버플로우 형님들의 내용을 빠르게 요약해 보겠습니다!
LoggerWriter class 만들어서 main.py에 로그 찍어주는 스크립트 추가해! 이겁니다 ㅎㅎ
main.py
class LoggerWriter:
def __init__(self, level):
# self.level is really like using log.debug(message)
# at least in my case
self.level = level
def write(self, message):
# if statement reduces the amount of newlines that are
# printed to the logger
if message != '\n':
self.level(message)
def flush(self):
# create a flush method so things can be flushed when
# the system wants to. Not sure if simply 'printing'
# sys.stderr is the correct way to do it, but it seemed
# to work properly for me.
self.level(sys.stderr)
# Create Logger if doesn't exist
Path("log").mkdir(parents=True, exist_ok=True)
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
handler = TimedRotatingFileHandler('log/error.log', when="midnight",
interval=1, encoding='utf8')
handler.suffix = "%Y-%m-%d"
handler.setFormatter(formatter)
logger = logging.getLogger()
logger.setLevel(logging.ERROR)
logger.addHandler(handler)
sys.stdout = LoggerWriter(logging.debug)
sys.stderr = LoggerWriter(logging.warning)
.......
main.py 위에 위 내용 그냥 그대로 갖다 넣으면 로그를 콘솔이 아닌 파일에 찍어주면서 모든 오류가 사라지고 noconsole 옵션으로. exe 파일을 무사히 배포할 수 있게 됩니다 ㅎㅎ
글 내용이 도움이 되셨다면 좋아요 부탁드립니다 ㅎㅎ
'독학 > python' 카테고리의 다른 글
[파이썬] requests 모듈을 사용한 python동적크롤링 따라하기 (0) | 2023.03.12 |
---|---|
[파이썬] 셀레니움 동적 크롤링 웹 자동화 python selenium example (0) | 2023.01.23 |
[파이썬] selenium 또는 requests를 이용한 동적 크롤링 python crawling (0) | 2022.11.12 |
[파이썬] 네이버 커머스 API requests post로 서버에 이미지 보내기 (8) | 2022.11.12 |
- Total
- Today
- Yesterday
- 상위노출프로그램
- JS독학
- 파이썬독학
- 웹앱독학
- CNC업그레이드
- 주식시장거품
- javascript
- 그림독학
- 파이썬실전
- 인플레이션
- GRBL
- 주식분석
- 경매동향
- 제로이드
- 주식독학
- 수부지추천
- 책추천
- 프로그래밍독학
- 경매참고자료
- selenium
- 주식종목
- 브리타정수기
- 파이썬셀레니움
- 책리뷰
- flutter네이버커머스api
- javascript독학
- 파이썬
- 네이버커머스api
- 자바스크립트독학
- 눈시림없는선크림
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |