본문 바로가기

SW 개발/Python33

Selenium 4.0 개선 사항 정리 - WebDriver 자동 로딩 가능 이전 포스팅에서 설명한 Web Crawling 방법에서 사용했던 Selenium이 3.0 버전에서 4.0으로 업그레이드 되었습니다. Selenium 3.0 버전 대비 4.0에서 가장 큰 개선 사항은 OS 별(Windows, Unbuntu, MacOS), Broswer 버전을 자동 감지하여 Web Driver 설치를 자동으로 할 수 있습니다. 이전 버전에서는 Chrome Driver를 버전별로 지정해서 수동으로 설치했었습니다. 만일 Chrome Version이 업데이트되는 경우 Web Driver도 같이 변경해야 하지만, Selenium 4.0부터는 OS와 Web Broswer에 맞는 Web Driver를 자동으로 다운로드하고 로딩이 가능합니다. Python Selenium과 BeautifulSoup을 활.. 2021. 12. 26.
Python 자동 테스트를 위한 Pytest 사용법과 예제 Python에서 Unittest의 가장 많이 사용하는 모듈은 Pytest와 Unittest입니다. unittest는 python 기본 모듈로 설치되고 JUnit와 같은 형식으로 테스트 코드를 간단하게 작성할 수 있고, Pytest는 unittest를 포함하여 다양한 형태의 texture 함수를 지원하고, 매우 다양한 옵션을 지원합니다. 또는 Pytest unittest 뿐 아니라 JUnit 등 다양한 테스트 framework을 호출할 수 있습니다. Test case를 쉽게 작성하고자 하는 경우에는 unittest를 사용하고, 고도화된 Test를 만들고자 하는 경우 pytest를 추천드립니다. Pytest 설치 Python unnittest는 기본 모듈로 별도 설치가 필요 없지만, pytest는 pip를 .. 2021. 12. 12.
Python 단위 테스트(Unit Test)를 위한 unittest 사용법과 예제 Python에서 단위 테스트를 unittest 사용법을 설명합니다. unittest는 Python 기본 Lib로 별도의 모듈을 설치할 필요가 없고, 사용법은 Java의 JUnit과 유사하여 쉽게 사용할 수 있습니다. Python unittest는 테스트 자동화, 자동화를 위한 설정, 종료, 각 테스트 case 실행하고 실행 결과를 report 할 수 있도록 구성되어 있습니다. unittest는 unittest.TestCase 의 함수를 상속받아 객체 지향적인 방법으로 각각의 함수를 지원합니다. Test Fixture: Test를 수행할 때 사전에 필요한 준비와 그와 관련된 동작을 실행합니다. 예를 들어 로그인이 필요한 기능에 대한 로그인을 테스트 전에 사전에 실행하거나, 필요한 데이터를 가져오기, 폴더 .. 2021. 12. 11.
Python Decorator를 이용한 함수 실행 시간 측정 방법 (Sample code) Python 함수의 실행 결과를 측정이 필요한 경우가 있습니다. 일반적으로 linux에서 time 명령어를 사용할 수 있고, Python code 자체에서는 @함수명으로 표시되는 decorator를 사용할 수 있습니다. Python 함수 실행 시간 측정 import time def elapsed(f): def wrap(*args): start_r = time.perf_counter() start_p = time.process_time() # 함수 실행 ret = f(*args) end_r = time.perf_counter() end_p = time.process_time() elapsed_r = end_r - start_r elapsed_p = end_p - start_p print(f'{f.__nam.. 2021. 12. 3.
Python 여러 버전 설치 방법 (3.x and 3.y 동시 설치) 상용 우분투 서버에 파이썬 프로그램을 하나의 설치 파일로 만들어서 배포하는 작업을 진행 중에 있습니다. 최대한 많은 리눅스 서버와 호환성을 유지하기 위해서 가장 낮은 버전의 우분투와 glibc 버전의 환경에서 설치 파일을 만들어야 합니다. 현재 사용하고 있는 서버의 우분투 버전을 조사한 결과 14.04, 16.04, 18.04 버전을 사용하고 있으며, 가장 낮은 14.04 버전을 기준으로 실행 파일을 생성하기로 했습니다. 즉, 우분투 14.04 서버에서 빌드한 프로그램은 14.04 이후 버전 (16.04, 18.04, 20.04) 서버에서 구동을 시킬 수 있습니다. 우분투 14.04 버전을 확인한 결과 Python 2.7.6 버전과 3.4 버전이 설치되어 있고, 설치 파일 생성을 위한 pyinstalle.. 2021. 9. 12.
Python 가상환경(Virtual Environment) 만들기 위한 virtualenv 명령어 및 실행 예제 Python은 2.x 버전부터 3.10 버전까지 개발되어 있습니다. 2.x버전과 3.x 버전에는 문법에 있어 많은 변경이 있었고, Python 3.x 버전에서도 기본적은 문법은 동일하나 함수 paramter 등의 변화가 있었습니다. Python은 1~2년 주기로 Major 버전 업그레이드가 진행되기 때문에 프로젝트를 진행할 때에는 일반적으로 과거의 특정 버전을 기준으로 개발합니다. 각 Python 버전 간의 차이로 발생하는 종속성 문제점을 해결하기 위해서 "가상 환경 virtualenv"를 지원합니다. 가상 환경은 아래와 같은 경우에 유용하게 사용합니다. 개발 서버에서 설치된 python verion과 별도의 project를 진행 (e.g. 서버는 python 3.8, 프로젝트 버전은 v3.6인 경우) .. 2021. 8. 24.
Python 2.x에서 3.x으로 코드 자동 변환: 2to3 와 __future__ 사용 Python 코드를 다루다 보면 기존 Python 2.x 에서 개발된 오픈 소스를 Python 3.x으로 migration 해야 하는 경우가 종종 있습니다. 이 경우 코드 한 줄씩 변경하는 것보다 일괄로 변경해주는 Tool을 활용하는 것이 편리합니다. Python에서는 2to3로 변화는 tool을 제공합니다. 이는 lib2to3 기반으로 사용하고 있고, Python3과 100% 호환성 있는 코드까지는 아니지만 많은 수 작업 부분을 줄일 수는 방법을 설명합니다. Python 2to3 설명서: Python 공식 문서 사용 결과: Python 3.x 버전과 100% 호환성이 있는 코드는 아니지만 수작업 부분을 많이 감소시킴 설치 2to3는 Python 3 설치 시 같이 설치됩니다. (참고로, 우분투에서 apt.. 2021. 8. 15.
Python 정규식(Regular Expression) re 모듈 사용법 및 예제 정규식 표현식(Regular Expression)은 문자열을 처리하는 방법 중 하나로 "특정 조건 또는 패턴"을 치환하는 과정을 쉽게 처리할 수 있는 방법입니다. Python에서 정규식 처리 모듈은 re 로, re 모듈에 대한 사용법과 예제를 설명하도록 하겠습니다. 정규식 re import re를 사용하기 위해서는 import re를 선언하고, re 내부 함수와 pattern을 정의하여 호출합니다. import re 정규식 re 함수 Python에서 re 모듈에 대한 설명은 링크에 있고, 주요 함수는 다음과 같습니다. re 함수 설명 사용 예 re.compile(pattern, flags=0) 정규식 객체로 compile함 정규식 객체는 match()와 search()에 사용 prog = re.compi.. 2021. 7. 19.
Python: JSON 개념과 json 모듈 사용법 Python JSON 사용 방법에 대해서 정리하고자 합니다. JSON은 Key-value를 양식을 가지는 텍스트 파일로 인터넷 상의 서버-클라이언트의 데이터 교환에 많이 사용되고 있습니다. 최근에서는 Web 서버와 client간의 통신 및 프로그램과 프로그램 사이의 데이터 표현 및 교환하는데 사용되는 사실 상의 표준입니다. Python에서는 json 모듈을 지원하고 있으면 인코딩/디코딩을 지원하고 있고, JSON 데이터와 Python 데이터는 1:1로 맵핑되어 사용하기 쉽니다. Python JSON 공식 문서는 여기를 참고해주세요. 1. JSON 이란 JSON 에 설명 및 예제를 참고해주세요. (출처: 위키백과) JSON(JavaScript Object Notation)은 속성-값 쌍(attribute–.. 2021. 7. 16.
Python으로 개행 문자(\n)가 포함된 JSON 읽기: JSONDecodeError 수정하기 Python json 모듈에서 개행 문자 "\r\n" 또는 " \n" 포함된 string을 json.loads() 함수로 dictionary로 객체로 변환할 때 발생하는 에러입니다. 개행 문자가 포함된 경우 json.loads() 함수 호출 시 "JSONDecodeError():Invalid control character" 에러가 발생하며 수정 방법은 ① json.loads() 호출 시 strict=True 값으로 전달하는 방법과 ② 원본 스트링에서 문구를 치환하는 방법 2가지가 있습니다. 에러 발생 예제 import json json_str = """{ "이름": "홍길동", "나이": 25, "문장": "첫 줄 문장 \n 두 번째 문장" }""" jdata_obj = json.loads(json_s.. 2021. 7. 14.
Python으로 압축 파일 다루기: Zipfile 과 shutil.make_archive() Python에서 압축 파일은 내장 모듈인 Zipfile 모듈과 shutil.make_archive()와 shutil.unpack_archive()을 이용하여 다룰 수 있습니다. Zipfile 모듈은 python 기본 내장 모듈로, Zip 파일을 압축하고, 읽고, 저장, 리스트를 얻어올 수 있습니다. 압축 알고리즘은 Deflate, BZip, LZMA 알고리즘을 지원합니다. 또한 4GB 이상의 Zip 파일인 Zip64도 처리할 수 있습니다. Zipfile 모듈의 문서는 링크를 참고해주세요. shutil.make_archive() 함수와 shutil.unpack_archive()은 zip, tar, gztar, bztar를 지원합니다. 코드 한줄로 폴더를 압축할 수 있습니다. Zipfile 모듈 - zip .. 2021. 1. 14.
Python 음수 인덱스: line.split('+')[-1] 또는 line.split('/')[-1] 의미 C 언어인 경우 array에 '음수'인덱스는 허용하지 않지만, Python인 경우 음수 인덱스를 허용하고 있습니다. list 나 array와 같은 sqeunce 객체의 인덱스를 음수로 지정하면 마지막 항목부터 접근하게 됩니다. 음수 인덱스는 "마지막 항목"부터 접근하면 다양한 경우에 유용하게 사용할 수 있습니다. 예제 #1 a = (0,1,2,3,4,5,6) a[-1]=6 a[-2]=5 a[-3]=4 a[-4]=3 예제 #2 line = http://abc.example.com/def/ghi line.split('/') → ['abc.example.com', 'def', 'ghi'] line.split('/')[-1] → 'ghi' 예제 #3 line = 'a+b+c+d' line.split('+') →.. 2021. 1. 8.
Python에서 URL 한글 깨짐 현상: quote_plus()와 unquote_plus() Python으로 URL 처리 시 한글이 포함되어 있는 경우 한글 깨짐 현상이 있을 수 있습니다. 이는 URL 처리 시 특수 문자는 포함될 수 없어 ascii로 변환하여 발생하는 현상으로 url.parse 모듈의 quote_plus()와 unquote_plus()를 통해서 해결할 수 있습니다. ※ 만일 quote()와 unqute() 함수로도 한글이 깨져 있다면 인코딩 scheme을 확인해야 합니다. 기본적으로 'utf8'로 인코딩 되어 있는 경우 문제가 없으나, euc-kr이나 cpc-949로 인코딩 된 경우라면 아래 함수 encoding 값을 설정해야 합니다. URL에 한글이 포함되어 있는 경우 Before https://apkpure.com/t-map-%EB%82%B4%EB%B9%84%EA%B2%8C.. 2021. 1. 8.
Python: 날짜와 시간 처리 함수(현재 날짜, 어제 날짜, UTC 시간) Python에서 날짜와 시간을 처리하는 datetime 모듈을 제공합니다. 현재 날짜와 시간 구하기 import datetime today =datetime.datetime.now() → 2020-11-29 21:21:22.933386 d1 = today.strftime("%Y%m%d") → 20201129 어제 날짜와 시간 import datetime today =datetime.datetime.now() → 2020-11-29 21:21:22.933386 yesterday = today - datetime.timedelta(1) → 2020-11-28 21:21:22.933386 d2 = yesterday.strftime("%Y%m%d") → 20201129 timedelta 함수 (출처: Ptyho.. 2020. 11. 30.
Python: xmltodict를 활용하여 XML를 JSON으로 변환하는 방법 일반적으로 REST API를 사용할 때 JSON을 많이 사용하고 있지만 일부 사이트는 XML 포맷을 사용해서 결과를 내려주고 있습니다. 본 포스팅은 XML을 읽어 JSON형태로 변환하는 방법을 설명합니다. Python에서는 XML 처리를 위해서 Elementary Tree를 지원하고 있습니다. 이는 tree구조로 데이터를 읽어 Dictionary 데이터 타입 대비해서 코드의 양이 다소 증가하게 됩니다. 기존 포스팅에서 설명을 했기 때문에 xmltodict 모듈 사용하도록 하겠습니다. xmltodict모듈은 아래 github 사이트와 참조 링크를 확인해주세요. Python xmltodict 모듈 사용이 필요한 경우: XML 을 JSON으로 변환할 때 사용 REST API 중 일부는 XML로 결과를 내려주는.. 2020. 11. 26.
Python 명령어 처리: Argparse 모듈 (ArgumentParser 사용 예제) Terminal에서 Python script을 터미널에서 실행할 때 명령어 옵션에 대한 parameter를 python으로 전달할 때 사용하는 방법입니다. 제가 작성했던 기존 code는 sys.argv 값을 확인해서 터미널 명령어 인자별로 값을 얻어서 python 변수에 할당하는 방법을 사용하고 있었습니다. 이 경우 명령어 parameter가 추가 또는 삭제하는 경우 if 문 하나씩 증가하는 불편함이 있습니다. Python에서는 Command line에서 argument처리를 위한 argparse 모듈을 지원합니다. ArgumentParser와 add_argument 함수를 조합하면 보다 편리한 명령어 Parser를 만들 수 있습니다. 아래 Usage: ./argv_test.py [parm] [param.. 2020. 9. 1.
Python에서 사용자 입력 받는 방법: input() Python에서 사용자 입력 값을 받는 input() 함수를 설명합니다. input() 함수는 string으로 입력을 받습니다. Python built-in함수로 별도 모듈의 import는 필요 없으며, 사용법 또한 매우 간단합니다. input()을 string으로 return 하기 때문에 separator를 사용해서 입력을 받는 경우 split() 함수를 활용하면 여러 개의 input을 받을 수 있습니다. > res = input() → 사용자 입력을 받아서 string으로 저장합니다. Sample code는 아래와 같습니다. def main_menu(): print ("------------------------------------------") print ("Select menu") print (.. 2020. 8. 31.
MobaXterm (Cygwin)에서 Python 및 PIP 설치 MobaXterm에서 Python을 설치하고 실행하는 방법을 설명합니다. MobaXterm은 내부적으로 Cygwin으로 동작하기 때문에 Cygiwin에서 Python을 설치하는 방법과 동일하며, MobaXterm 나름의 Package update 기능을 지원하고 있기 때문에 MobaXterm 구동 상태에서 패키지 업데이트가 가능합니다. MobaXterm 실행 상태에서 상단 메뉴의 ① Packages 메뉴를 선택합니다. 해당 메뉴를 선택하면 cygwin의 설치 정보를 업데이트하고 패키지를 선택하는 옵션을 보여줍니다. MobaXterm의 package update 메뉴에서 ② show lib/devel 옵션을 활성화하고, ③ 패키지 검색창에서 'python3-dev'를 입력합니다. 설치하고자 하는 packa.. 2020. 8. 31.
Python Error: #!/usr/bin/env python3: 그런 파일이나 디렉터리가 없습니다 (No such file or directory) Python code를 작성하다 보면 #!/usr/bin/env python3 구문에서 에러가 발생하는 경우가 있습니다. 예를 들어 윈도에서 작성한 파이썬 파일을 리눅스에서 수정 및 실행을 하다 보면 에러가 발생할 수 있습니다. 이전 포스팅 (https://kibua20.tistory.com/73)에서는 윈도우와 리눅스에서 줄 바꿈 문자가 문제가 되는 경우도 있고, 아래와 같이 윈도우와 리눅스의 UFT8 인코딩 방식에 의해서 에러가 발생하는 경우도 있습니다. Python code: Code에는 문제가 없다. #!/usr/bin/env python3 # -*- coding:utf-8 -*- import os print ('test') 에러 메시지 #!/usr/bin/env python3: 그런 파일이나 디.. 2020. 8. 19.
Python: OSError: [Errno 98] Address already in use (Flask) Python으로 Web framework인 Flask를 공부하다가 발생하나 에러입니다. Flask에서 5000 포트를 사용하고 있는데 Flask 모듈이 비정상적으로 종료해서 5000 포트를 잡고 있어 발생하는 에러입니다. 에러 메시지 Traceback (most recent call last): File "/usr/lib/python3.8/runpy.py", line 193, in _run_module_as_mainreturn _run_code(code, main_globals, None, File "/usr/lib/python3.8/runpy.py", line 86, in _run_codeexec(code, run_globals) (중략) File "/usr/local/lib/python3.8/dist.. 2020. 7. 26.
Python code 숨기는 방법: PyInstaller로 실행 파일 만들기 파이썬을 작성한 코드는 byte code인 pyc파이로 변환하더라도 디컴파일이 쉽게 되기 때문에 코드를 숨길 수가 없습니다. (참고) 이에 비해 PyInstaller는 Py파일을 실행파일로 만들 수 있어 쉽게 코드를 숨길 수 있고, 필요한 lib 도 포함하고 있어 상용 서버에 파이썬으로 개발한 SW를 배포하기에 편리합니다. PyInstaller에 대한 설명은 아래 동영상을 참고해주세요. ※ 실행파일(.exe or ELF)도 Reverse Engineering으로 디컴파일이 가능하기 때문에 절대 신뢰하면 안되고, py나 pyc 보다는 그나마 코드를 숨기는 방법입니다. PyInstaller 설명 (출처: https://www.youtube.com/watch?v=RMkPGjGhzxg) 주의해야 점 PyInst.. 2020. 7. 21.
Python 폴더 및 파일 처리 함수 모음 Python 폴더 및 파일 처리 명령어 모음입니다. Python에서 폴더 및 파일을 처리하기 위해서는 import os 해야 합니다. 한 가지 주의할 점은 리눅스와 윈도우의 파일 경로 처리 방식이 다르기 때문에 파일 경로를 python 코드에서 하드 코딩하면 윈도우와 리눅스에서 호환성을 보장이 안되고, 반드시 os.path.join() 로 처리해야 합니다. import os 현재 작업 폴더 얻어오기: os.getcwd() os.getcwd() → /home/kibua/git/devDocs/file 현재 작업 폴더 변경하기: os.chdir() os.chdir('/home/kibua/git/devDocs') → /home/kibua/git/devDocs 특정 폴더의 폴더와 파일 리스트 확인하기: os.li.. 2020. 7. 17.
Python: 폴더 백업 기능 구현 (7zip 압축, Sample code) 특정 폴더(working_folder)를 일정 시간 간격으로 백업을 해야 기능이 필요해서 python으로 구현한 내용을 공유합니다. 특정 폴더의 백업 기능의 상세 구현 사항은 아래와 같습니다. Working folder의 하위에 모든 파일을 backup 한다. (주기적으로 실행은 crontab 사용) 하드 디스크를 용량을 절약하기 위해서 7zip 파일로 압축한다. (압축 포맷은 효율이 좋은 7 zip 사용) 백업 폴더에서 백업 파일 7zip 파일의 개수는 미리 설정한 최대 개수를 초과하지 않는다. 백업 파일의 최대 개수가 초과하는 경우 오래된 파일부터 삭제한다. 7zip 파일은 비밀 번호 설정한다. 아래 코드는 우분투를 환경에서 동작하는 검증한 code이고, os.system()를 수정하면 windows.. 2020. 7. 9.
Python 에러: /usr/bin/env: `python3\r': 그런 파일이나 디렉터리가 없습니다 Python code를 *.py 파일에 작성하고 terminal에서 실행하는 방법은 python 명령어 뒤에 py 파일을 인자로 전달하거나, 일반 실행 파일처럼./test.py로 직접 실행할 수 있다. test.py 파일을 바로 실행하기 위해서는 interpreter 지정 ( #!/usr/bin/env python3)있어야 하고, 실행 권한이(chmod 766) 있어야 한다. #python으로 test.py을 실행하는 방법 $ python3 test.py $ ./test.py test.py 파일 #!/usr/bin/env python3 # -*- coding:utf-8 -*- 에러 메시지 터미널에서 test.py 을 실행했을 때 "/usr/bin/env: `python3\r': 그런 파일이나 디렉터리가 .. 2020. 7. 3.
Python 소스 숨기는 방법: pyc 활용 (Bytecode로 컴파일) Python은 기본적으로 인터프리터 언어이기 때문에 별도의 컴파일과 링크 없이 실행(=해석) 가능합니다. 상용 프로그램으로 배포하는 경우나 보안 상 파이썬 소스 코드의 일부분을 숨겨야 하는 경우 Byte code로 변환하여 pyc (pyo) 파일을 사용할 수 있습니다. pyc 파일은 C 언어처럼 기계어로 컴파일한 것이 아니라 Byte code로 '변환'한 것이기 때문에 조금만 노력하면 원래의 소스 코드로 de-compile이 가능하기 때문에 절대적으로 소스 코드의 보안이 유지된다고 믿어서는 안 됩니다. 다만 소스코드를 보기 힘들게 하는 정도로 이해해야 합니다. Python 공식 문서에는 pyc로 컴파일하는 py_compile()는 아래와 같이 설명되어 있습니다. https://docs.python.org.. 2020. 6. 30.
Python 표준 입출력(stdin/stdout) 활용 - 리눅스 프로그램과 연동 작업 동기 Command line으로 email 전송 프로그램이 필요해서 Gmail API와 Python를 사용해서 sendmail() 함수를 구현하였다. Python으로 구현한 sendmail() 함수의 1차 구현은 아래와 같이 sender, to, subject, attachment, message를 파라미터를 받는 함수로 구현하였다. 앞에 4개 인자(sender, to, subject, attachment)는 까지는 함수 호출을 한 줄로 끝낼 수 있지만, mesaage (=email 내용)은 경우에 따라서 매우 길어져서 다른 방법을 찾아야 했다. 기존에 Postfix와 sendmail과 mail의 호출 예를 보니, bash의 | 와 2020. 6. 29.
Python JSON 사용 시 TypeError: Object of type bytes is not JSON serializable Python 3.8 버전에서 Dictionary 데이터를 JSON변환 시 발생했던 TypeError: Object of type bytes is not JSON serializable 에러에 대한 수정 사항입니다. json.dumps()함수는 일반 obj를 JSON 포맷의 string으로 serialize 한다고 설명되어 있다(아래 그림) . 즉, Dictionary를 JSON으로 변환하기 위해서는 일반적으로 string으로 직렬화하여 전달해야 하지만, 직렬화가 정의되지 않은 byte array 로 전달하여 Type error 에러가 발생하는 것입니다. decode('utf8') 함수를 사용해서 byte array를 string으로 변환하여 수정할 수 있습니다. 수정 전 코드 def CreateMessa.. 2020. 6. 29.
Python smtplib 사용한 email 발송 예제 (gmail) 이전 Post에서는 우분투에 postfix를 설치하고 gmail을 전송을 하는 방법을 확인하였습니다. 본 글은 python 에 기본 내장되어 있는smtplib를 사용하는 방법에 대해서 정리하였습니다. smtplib를 사용하면 간단하게 email 전송이 가능하나, python script 상에서 계정과 Password 가 노출된다는 문제점이 있습니다. 참고로, 아이디와 패스워드가 노출 없이 진행하기 위해서는 Google Gmail API를 사용할 수 있으며, 이는 access token으로 인증을 받아서 1 시간만 유효하기 때문에 보안 관점에서 유리합니다. [개발환경] - [Memo] 우분투에서 gmail활용하여 command line으로 email 전송 [모바일/REST API] - Google Gmai.. 2020. 6. 28.
Python SyntaxError: Non-ASCII character in file on, but no encoding declared Python 에서 코딩을 잘하고 있다가 한글을 사용하는 경우 "SyntaxError: Non-ASCII character, but no encoding declared" 가 발생한다. 이 경우 py 파일의 최상단에 encoding type을 선언해주면 해결된다. 수정 전: def CreateMessage(sender, to, subject, message_text): message = MIMEText(message_text) message['to'] = to message['from'] = sender message['subject'] = subject try: return {'raw': base64.urlsafe_b64encode(message.as_string())} except: return {'r.. 2020. 6. 28.
Python 2.7과 3.8호환성: a bytes-like object is required, not 'str'에러 수정 Python 2.7의 코드를 Python 3.8 버전에서 재 사용하는 경우 가끔 Type error가 발생한다. 개발하고 있는 python code가 2.7 버전과 3.8 버전에서 돌려야 하는 경우 아래와 같이 수정할 수 있다. 버전을 체크하는 경우 버전을 계속 올라감에 따라서 확인이 필요하기 때문에 code 유지 보수가 힘들다. 이 경우 try: except: 구문으로 exception 발생 여부를 체크해서 수정할 수 있다. Python 2.7 에서는 try 구문에서 exception없이 처리하고, 3.8 버전에서 except구문으로 처리 가능하다. 수정 전 Code: def CreateMessage(sender, to, subject, message_text): message = MIMEText(me.. 2020. 6. 28.