모듈 만들기
먼저 [module_basic] 디렉토리를 만들어 다음의 두 파일을 만들어서 넣자. main.py가 메인코드로 활용할 부분이다.
test_module.py
main.py
▷ 쉬운 모듈 만들기
(module_basic/tset_module.py)
# test_module.py 파일
PI = 3.141592
def num_input():
output = input("숫자 입력> ")
return float(output)
def get_circumference(radius):
return 2 * PI * radius
def get_circle_area(radius):
return PI * radius * radius
|
(module_basic/tset_main.py)
# main.py 파일
import test_module as test
radius = test.num_input()
print(test.get_circumference(radius))
print(test.get_circle_area(radius))
|
[실행결과]
PS D:\app\python\module_basic> python main.py 숫자 입력> 100 628.3184 31415.92 |
__name__ = "__main__"
다른 사람들이 만든 파이썬 코드를 보다 보면 __name__ = "__main__" 이라는 코드를 많이 볼 수 있다. 이 의미가 무엇인지 자세히 살펴보자.
↘ __name__
파이썬 코드 내부에서는 __name__이라는 변수를 사용할 수 있다. __name__이라는 변수에 어떤 값이 있는지 확인해보자.
프로그래밍 언어에서는 프로그램의 진입점을 엔트리 포인트 또는 메인이라고 부른다. 그리고 이러한 엔트리 포인트 또는 메인 내부에서의 __name__은 "__main__"이다.
↘ 모듈의 __name__
엔트리 포인트가 아니지만 엔트리 포인트 파일 내에서 import 되었기 때문에 모듈 내 코드가 실행된다. 모듈 내부에서 __name__을 출력하면 모듈의 이름이 나타난다. 간단하게 코드를 구성해 보자.
▷ 모듈 이름을 출력하는 모듈 만들기
(module_main/main.py)
# main.py 파일
import test_module
print("# 메인의 __name__ 출력하기")
print(__name__)
print()
|
(module_main/test_module.py)
# test_module.py 파일
print("# 모듈의 __name__ 출력하기")
print(__name__)
print()
|
[실행결과]
PS D:\app\python\module_main> python main.py # 모듈의 __name__ 출력하기 test_module # 메인의 __name__ 출력하기 __main__ |
main.py 파일을 실행하면 엔트리 포인트 파일에서는 __main__을 출력하지만, 모듈 파일에서는 모듈 이름을 출력하는 것을 볼 수 있다.
↘ __name__ 활용하기
엔트리 포인트 파일 내부에서는 __name__이 "__main__"이라는 값을 갖는다. 이를 활용하면 현재 파일이 모듈로 실행되는지 엔트리 포인트로 실행되는지 확인할 수 있다.
▷ 모듈 활용하기
(module_exam/test_module.py)
PI = 3.141592
def num_input():
output = input("숫자 입력> ")
return float(output)
def get_circumference(radius):
return 2 * PI * radius
def get_circle_area(radius):
return PI * radius * radius
print("get_circumference(10)", get_circumference(10))
print("get_circle_area(10)", get_circle_area(10))
|
(module_exam/main.py)
import test_module as test
radius = test.num_input()
print(test.get_circumference(radius))
print(test.get_circle_area(radius))
|
[실행결과]
PS D:\app\python\module_exam> python main.py get_circumference(10) 62.83184 get_circle_area(10) 314.1592 숫자 입력> 10 62.83184 314.1592 |
모듈에서 활용 예로 사용했던 코드까지 출력된다. 모듈로 사용하고 있는데 내부에서 출력이 발생하니 문제가 된다. 이때 현재 파일이 엔트리 포인트인지 구분하는 코드를 활용한다. 조건문으로 __name__이 "__main__"인지 확인만 하면 된다.
▷ 엔트리 포인트 확인하는 모듈 만들기
(module_exam/test_module.py 수정)
PI = 3.141592
def num_input():
output = input("숫자 입력> ")
return float(output)
def get_circumference(radius):
return 2 * PI * radius
def get_circle_area(radius):
return PI * radius * radius
if __name__ == "__main__": #조건추가~~
print("get_circumference(10)", get_circumference(10))
print("get_circle_area(10)", get_circle_area(10))
|
[실행결과]
PS D:\app\python\module_exam> python main.py 숫자 입력> 10 62.83184 314.1592 |
모듈의 출력 부분은 출력하지 않는다. 자주 사용되는 형태의 코드이다.
패키지
쉬운 이해를 위해 import로 가져오는 모든 것을 모듈이라고 설명했다. 그런데 원래 pip은 Python Package Index의 줄임말로 패키지 관리 시스템이다. 그럼 패키지와 모듈은 무엇이 다를까? 결론부터 말하면 모듈이 모여서 구조를 이루면 패키지라고 부르는 것이다.
↘ 패키지 만들기
폴더구성: test_package (패키지 폴더)
파일생성: main.py (엔트리 포인트로 사용)
모듈이 모여 구조를 이루면 패키지가 된다고 했다. test_package 폴더 내부에 모듈을 하나 이상 넣으면 된다. 예제로 mod_a.py , mod_b.py 파일을 생성해보자.
파일생성: mod_a.py, mod_b.py
▷ 패키지 만들기(1)
(module_package/test_package/mod_a.py)
#./test_package/mod_a.py 의 내용
variable_a = "a 모듈의 변수"
|
(module_package/test_package/mod_b.py)
#./test_package/mod_b.py 의 내용
variable_b = "b 모듈의 변수"
|
(module_package/main.py)
# 패키지 내부의 모듈을 읽어 들인다.
import test_package.mod_a as a
import test_package.mod_b as b
# 모듈 내부의 변수를 출력한다.
print(a.variable_a)
print(b.variable_b)
|
[실행결과]
PS D:\app\python\module_package> python main.py a 모듈의 변수 b 모듈의 변수 |
↘ __init__.py 파일
패키지를 읽을 때 어떤 처리를 수행해야 하거나 패키지 내부의 모듈들을 한꺼번에 가져오고 싶을 때가 있다. 이럴 때는 패키지 폴더 내부에 __init__.py 파일을 만들어 사용한다.
[ test_package 폴더 내부에 __init__.py 파일 추가하기]
패키지를 읽어 들일 때 __init__.py를 가장 먼저 실행한다.
따라서 패키지와 관련된 초기화 처리 등을 할 수 있다. __init__.py에서는 __all__이라는 이름의 리스트를 만드는데, 이 리스트에 지정한 모듈들이 from <패키지 이름> import * 를 할 때 전부 읽어 들인다.
▷ 패키지 만들기(2)
(module_package/test_package/__init__.py)
# "from test_package import *"로
# 모듈을 읽어 들일 때 가져올 모듈
__all__ = ["mod_a", "mod_b"]
# 패키지를 읽어 들일 때 처리를 작성할 수 있다.
print("test_package를 읽어 들였습니다")
|
(module_package/main_1.py)
# 패키지 내부의 모듈을 모두 읽어 들인다.
from test_package import *
print(mod_a.variable_a)
print(mod_b.variable_b)
|
※ __init__.py 파일의 역할
파이썬 3.3 이전 버전에서는 __init__.py 파일이 무조건 있어야 패키지로 작동했지만, 이후 버전에서는 __init__.py 파일이 없어도 폴더 내부에 파이썬 파일이 들어 있기만 하면 패키지로 작동한다.
(좀 더 알아보기1) 텍스트 데이터
파일은 크게 텍스트 데이터와 바이너리 데이터로 구분된다. 컴퓨터 내부적으로 모든 처리를 0과 1로 이루어진 이진 숫자로 수행한다. 따라서 원래 컴퓨터 내부에 있는 모든 것들은 이진 숫자로 구성되어 있다. 실제로 "Hello Python" 이라는 글자를 메모장에 적고 저장하면 내부적으로는 2진수로 저장한다.
우리가 쉽게 읽을 수 있는 형태의 데이터를 텍스트 데이터라고 부른다. 텍스트 데이터는 쉽게 읽을 수 있는 것은 물론이고, 텍스트 데이터만 있으면 쉽게 편집도 할 수 있다. 우리가 입력해 왔던 모든 코드 역시 텍스트 데이터이다.
(좀 더 알아보기2) 바이너리 데이터
텍스트 에디터에서 '100'이라는 숫자를 표현하는 경우를 생각해 보자. 100이라는 글자는 '1', '0', '0'이라는 글자로 이루어져 있으며, ASCII 코드를 살펴보면 '49', '48', '48'로 변환할 수 있다.
☞ 3바이트를 차지하는 텍스트 데이터100[49 48 48]
00110001 00110000 00110000 |
그런데 100을 '1', '0', '0'으로 나타내는 텍스트 데이터가 아니라, 곧바로 '100'이라는 숫자로 저장한다면 어떨까? 세 글자로 표현하던 것을 한 글자로 표현할 수 있게 되므로 용량이 절약될 것이다.
☞ 1바이트를 차지하는 바이너리 데이터 100[100]
01100100 |
ASCII 코드를 살펴보면 100이라는 숫자는 'd'에 해당한다. 따라서 텍스트 에디터로 이러한 내용의 파일을 읽어 들이면 'd'라는 내용이 들어 있을 것이다. 즉, 텍스트 데이터로 표현할 경우 의미를 알 수 없는 데이터가 되어 버리는 것이다. 컴퓨터에서는 이처럼 텍스트 에디터로 열었을 때 의미를 이해할 수 없는 데이터를 바이너리 데이터라고 부른다.
바이너리 데이터의 대표적인 예는 이미지와 동영상이다. 이미지와 동영상은 텍스트 데이터로 표현할 수 없다. 이미지 파일의 내용을 제대로 읽으려면 '이미지 뷰어'가 필요하며, 내용을 수정하려면 '그림판', '포토샵'과 같은 별도의 프로그램이 필요하다. 따라서 바이너리 데이터는 텍스트 데이터보다 사용하기 어렵고 사람이 인식하기 힘들다고 할 수 있다.
↘ 인코딩과 디코딩
사실 텍스트 데이터도, 바이너리 데이터도 2진수의 집합일 뿐이다. 텍스트 데이터를 맞춰서 우리가 읽기 쉬운 글자로 보여 주려면, 그리고 바이너리 데이터를 읽어서 이미지로 보여 주려면 변환을 해야 한다. 이를 인코딩 방식이라고 부른다.
인코딩 방식에는 수많은 방법이 존재한다. 텍스트 데이터의 경우 ASCII, UTF-8, EUC-KR 등이 있다. 바이너리 데이터의 경우에는 이미지만 해도 JPEG, PNG, GIF 등이 있다.
인코딩 방식을 기반으로 A라는 형식을 B라는 형식으로 변환하는 것을 인코딩이라고 부르고, 이렇게 인코딩된 데이터를 반대로 돌리는 것을 디코딩이라고 부른다.
↘ 텍스트 데이터와 바이너리 데이터
바이너리 데이터는 문자열(텍스트)이 아니므로 문자열과 관련된 기능(len() 함수 등)을 활용할 수 없다. 그런데 바이너리 데이터는 글자가 아니라고 했는데 왜 글자가 써져 있는 걸까? 이는 단순히 파이썬이 바이너리를 무조건 ASCII 코드표 등으로 인코딩해서 출력해 주기 때문이다.
↘ 인터넷의 이미지 저장하기
인터넷에서 이미지를 읽고 저장하는 방법을 살펴보자. 일단 웹에서 데이터를 가져오는 부분까지는 동일하며 데이터를 텍스트 데이터가 아니라 바이너리 데이터로 저장해야 한다.
저장 방법은 굉장히 간단한데, 파일을 열 때 다음과 같이 뒤에 "b"를 붙여주면 된다. 이렇게 "rb" 또는 "wb"로 적으면 바이너리 형식으로 파일을 읽고 써준다.
▷ 이미지를 읽어 들이고 저장하기
# 모듈을 읽어 들인다.
from urllib import request
# urlopen() 함수로 한빛출판사 이미지를 읽는다.
output = target.read()
print(output)
# write binary(바이너리 쓰기) 모드로
file = open("output.png", "wb")
file.write(output)
file.close()
|
[실행결과]
PS D:\app\python> python binary_download.py b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01\x04\x00\x00\x00,\x08\x06\x00\x00\x00\x83\x80\xc6\xe5\x00\x00\x00\x19tEXtSoftware\x00Adobe ImageReadyq\xc9e<\x00\x00\x0f/IDATx\xda\xec]\ttU\xc5\x19\xfe\xb3\x11 D\x11\x13\x0cF\x08\x11\x14KEA\xf6M\xd0\xd6\xa3\xb8\xe1\x12W\x8a\xa8\xc7R\xac\xb5`\x05\xad\xed\xa9\xbbb\x17\n\xd4\xa5Pj\x05\x11+4*\n\x15\xc4\xca\xa2\ ...(중간 생략)... xe33\x0e\x1fpX\xc5 P\xa4\x9b_\x93\xa6\x18\x05\x04M\x9a4i\x02\xfd_\x80\x01\x00\xed$ky]PVU\x00\x00\x00\x00IEND\xaeB`\x82' PS D:\app\python> |
코드를 실행하면 바이너리 데이터를 출력한다. 같은 폴더에 저장된 output.png 파일을 열어 보면 다운로드된 이미지를 확인할 수 있다.
모듈을 분석하는 방법 (연습문제X)
파이썬 모듈은 코드가 모두 공개되어 있다. 컴퓨터에 설치된 모듈을 찾아보면 모듈의 코드를 확인할 수 있다. pip list 명령어를 사용해서 설치된 명령어를 확인해 보자.
PS D:\app\python> pip list Package Version -------------- ----------- beautifulsoup4 4.11.1 click 8.1.3 colorama 0.4.5 Flask 2.1.3 itsdangerous 2.1.2 Jinja2 3.1.2 MarkupSafe 2.1.1 pip 22.0.4 primePy 1.3 setuptools 58.1.0 soupsieve 2.3.2.post1 Werkzeug 2.1.2 WARNING: You are using pip version 22.0.4; however, version 22.1.2 is available. You should consider upgrading via the 'C:\Users\이현민\AppData\Local\Programs\Python\Python310\python.exe -m pip install --upgrade pip' command. PS D:\app\python> |
그리고 pip show <설치된 모듈>을 입력하면 모듈이 설치된 위치를 확인할 수 있다.
PS D:\app\python> pip show beautifulsoup4 Name: beautifulsoup4 Version: 4.11.1 Summary: Screen-scraping library Home-page: https://www.crummy.com/software/BeautifulSoup/bs4/ Author: Leonard Richardson Author-email: leonardr@segfault.org License: MIT Location: c:\users\xxx\appdata\local\programs\python\python310\lib\site-packages Requires: soupsieve Required-by: PS D:\app\python> |
Location이라고 적혀 있는 부분에 모듈이 설치되어 있다. 해당 폴더로 들어가면 여러 모듈이 설치된 모습을 확인할 수 있다.
각각의 폴더가 모듈의 이름을 나타낸다. 예를 들어 BeautifulSoap 모듈을 나타내는 bs4 폴더를 열어 보면 다음과 같은 파일들이 나온다.
파일 하나하나 열어 보면 분석해 보기 바란다. 코드가 기니깐 오랜 시간을 가지고 차근차근 분석하면 된다. 그리고 모듈들이 꼬리를 문다고 그런 모듈들을 모두 타고 올라가며 분석할 필요는 없다. '이런 기능을 구현할 때 조건문과 반복문이 아니라 리스트와 클래스를 활용했구나'라는 형태로 스스로 생각하기 힘들었던 부분들을 찾을 수 있으면 그것으로 충분하다.
여기까지.
'개발자모드 > 혼자공부하는파이썬' 카테고리의 다른 글
[파이썬#24][고급] 클래스의 추가적인 구문 - isinstance(), 클래스 변수와 함수, 상속, 가비지컬렉터, 게터와 세터 ★혼공파 최종편★ (0) | 2022.07.28 |
---|---|
[파이썬#23][고급] 클래스의 기본 (객체 지향 언어, 추상화, 인스턴스, 생성자, 메소드) (0) | 2022.07.26 |
[파이썬#21][고급] 외부 모듈 (모듈 설치 pip install, BeautifulSoup, Flask) (0) | 2022.07.22 |
[파이썬#20][고급] 표준 모듈 (math, random, sys, os, datetime, time, urllib) (0) | 2022.07.20 |
[파이썬#19] 예외 고급 (Exception, raise 구문, 깃허브 GitHub ) (0) | 2022.07.18 |
댓글