ID:
PW:

     0 분
     6 분

엔지니어 돌종
  dolljong
프로그래밍 Tips
프로그래밍에 관한 Tip을 공유하는 곳입니다.


[python] (엔지니어를 위한) 파이썬 시작하기[8-1]패키지
이석종  2022-09-04 21:44:09, 조회 : 468, 추천 : 67
- Download #1 : engpython8.png (13.2 KB), Download : 14


[8]에서 계속

3. package(패키지)

package는 디렉토리다. 디렉토리 이름이다. 예를 들어 도로설계 패키지를 만든다고 하자. 도로 안에는 토공구간, 교량구간, 터널구간이 있을 것이다. 그러면 도로설계 패키지의 이름을 roaddesign이라고 하고 그 안에 도로선형관련은 road.py 토공은 earth.py, 교량은 bridge.py, 터널은 tunnel.py라는 이름으로 각각 패키지를 만들었다고 하자.  이렇게 package로 만드는 이유는 다른사람과 공유하기 쉽다는 장점이 있다. 디렉토리 전체를 전달하면 되기 때문이다.

도로설계 패키지 디렉토리는 아래와 같이 구성될 것이다.

roaddesign
   road.py
   earth.py
   bridge.py
   tunnel.py

 

각각의 모듈들의 내용은 아래와 같다. road.py에는 선형관련 함수 align()가, earth.py에는 절토에 관련된 함수 cutting()이, bridge.py에는 거더에 관련된 함수 girder()가, tunnel.py에는 제트팬에 관련된 함수 jetpan()함수를 정의했다. 각자 아무 디렉토리에 만들어보자. 나중에 이 디렉토리는 원하는 프로젝트 아래로 복사하는 것도 실습해 볼 것이다.

 

print("Road design")

def align():
  print(
"Road design align function")

 

 

print("Earth work")

def cutting():
  print(
"Earth work cutting function")

 

print("Bridge work")

def girder():
  print(
"Bridge work girder function")

 

print("Tunnel Work")

def jetpan():
  print(
"Tunnel Work jetpan function")

 

각각의 모듈들의 첫번째 줄은 import되면서 바로 실행된다. import되었다는 것을 표시해줄 것이다.

 

이 roaddesign 패키지는 내가 쓰려고 만들었지만 이것을 다른 사람들도 쓸 때를 대비해서 별도의 패키지로 만든 것이다. 이제 이 패키지(디렉토리)를 불러와(import해서) 써보자.

 

내가 작업하는 폴더가 d:\myproject\라고 하자. 이전에 만들었던 roaddesign디렉토리를 myproject에 복사(또는 만들고)하고 myproject 디렉토리로 이동해서 python을 실행한다.

 

(base) D:\>cd myproject
(base) D:\myproject>python
Python
3.9.7 (default, Sep 16 2021, 16:59:28) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
>>>

 

이제 roaddesign 패키지를 import할 것이다. 이전에 설명했듯이 from을 이용한다.

>>> from roaddesign import road, earth, bridge, tunnel
Road design
Earth work
Bridge work
Tunnel Work

 

import되면서 실행된 print문 덕분에 네개의 모듈이 모두 성공적으로 import된 것을 알 수 있다. 이제 각 모듈에 있는 함수들을 써보자. road.py모듈에는 align()이라는 함수가 있었다. align()함수를 쓰기위해서 모듈명을 명시해줘야 한다는 것을 기억하자. 다른 모듈의 함수들도 마찬가지다.

>>> road.align()
Road design align function
>>> bridge.girder()
Bridge work girder function

 

그런데 왜? from roaddesign import *를 쓰지 않고 네개의 모듈명을 다 써줬을까? *가 모든 것을 의미하는 것이라고 했다면 *를 쓰는 것이 편하지 않을까? 시도해보자. exit()으로 파이썬 인터프리터를 빠져 나왔다가 다시 파이썬 인터프리터로 들어간 다음에 *로 import해보자.

>>> from roaddesign import *

 

아무 일도 안 벌어진다. 각 모듈이 import될 때 메시가 출력되어야 하는데 아무것도 안보인다. 그렇다면 road.py모듈의 align()함수를 불러와보자. road가 정의되어있지 않다는 것이다.

>>> road.align()
Traceback (most recent call last):
  File
"", line 1, in
NameError: name
'road' is not defined

 

역시 import에 실패한 것이다. from roaddesign import * 했을 때 아무런 에러 메시지가 보이지 않았다면 import에 성공한 것 아니었나? import가 안된 것의 비밀은 *에 있다. 패키지(디렉토리)에 대해서 *가 사용될 때 불러올 모듈들(py파일들)의 목록은 따로 정해줘야 한다. 앞의 예에서는 *에 대한 목록을 정해주지 않았기 때문에 아무 모듈들도 불러오지 않은 것이다. 패키지에 대해 *에 대한 목록은 패키지 디렉토리에 __init__.py파일에 써준다. __init__.py 이 파일은 파일명에서도 눈치챌 수 있듯이 패키지가 import될 때 수행할 명령들을 정의해주는 일종의 설정파일이다. 파이썬에서 __로 시작하고 __로 끝나는 파일들은 설정파일이라고 생각하면 된다. __init__.py파일을 만들어보자.

<__init__.py>

__all__ = ['road', 'earth', 'bridge', 'tunnel'

 

이 파일을 roaddesign디렉토리에 저장하면 roaddesign 디렉토리 아래에는 아래와 같이 5개의 파일이 있게 된다.

 roaddesign
   __init__.py
   road.py
   earth.py
   bridge.py
   tunnel.py

 

이제 exit()으로 파이썬 인터프리터를 빠져나왔다가 다시 파이썬 인터프리터를 실행하고 *를 이용해서 import해보자. 메시지가 출력된 걸 보면 제대로 import되었다. 함수를 불러와보자. 잘 실행된다.

>>> from roaddesign import *
Road design
Earth work
Bridge work
Tunnel Work
>>> road.align()
Road design align function

 

 

__init__.py

__init__.py에 대해서 좀더 알아보자. 패키지가 import될 때 자동으로 실행되는 파일이라고 생각하면 된다. 그러면 이 파일 안에서 모듈들을 import하면 되지 않을까?

<__init__.py>

from . import road
from . import earth
from . import bridge
from . import tunnel

 

__init__.py안에 import문을 4개 넣었다. from .의 .은 현재 디렉토리라는 뜻이다. 어떤 디렉토리일까? python이 실행된 디렉토리일까? 아니면 roaddesign디렉토리일까? 당연히 __init__.py이 있는 디렉토리다. 이 내용은 __init__.py안에 있는 내용이라는 걸 기억하자. 즉 __init__.py이 있는 roaddesign디렉토리에서 road.py, earth.py, bridge.py, tunnel.py을 불러오라는 뜻이다. 이렇게 __init__.py의 내용을 바꾸고 난 다음에 roaddesign을 불러와 보자. 파이썬을 다시 실행하고 roaddesign을 import하면 제대로 import되는 걸 확인할 수 있다.

>>> import roaddesign
Road design
Earth work
Bridge work
Tunnel Work

 

이렇게 import하면 함수는 어떻게 사용해야 할까?  road.align()은 에러가 발생한다.

>>> road.align()
Traceback (most recent call last):
  File
"", line 1, in
NameError: name
'road' is not defined

 

패키지명까지 써줘야 에러가 발생하지 않는다. roaddesign이라는 패키지안에서 각 모듈들을 import했다는 것을 기억하자.

>>> roaddesign.road.align()
Road design align function

 

import as 키워드

파이썬 패키지를 불러올 때 별명을 정해줄 수 있다. as 뒤에다 별명을 써주면 된다. roaddesign의 별명을 rd로 해보자. roaddesign대신 rd를 사용할 수 있다. 간결해지는 장점이 있다. 패키지명은 패키지의 기능을 잘 나타낼 수 있게 짓다보면 좀 길게 된다. 그래서 as를 이용해 별명으로 쓰는 경우가 많다. 예를 들어 데이터 조작 및 분석에 유용하게 쓰이는 pandas라는 패키지는 pd로 줄여서 쓰고, 행렬이나 수치연산 기능을 가지고 있는 numpy는 np로 줄여서 쓴다. 다른 단어로 줄여서 써도 되지만 보통은 전통(?)을 따른다. 

>>> import roaddesign as rd
>>> rd.road.align()
Road design align function

 

 

scope

이 대목에서 알고 넘어가야 할 것이 하나 있다. 다른 프로그래밍 언어에도 있는 개념인데 scope이라는 것이다. 예를 들어 1학년 1반에도 홍길동이 있고 1학년2반에도 홍길동이 있다고 하자. 그러면 그 둘을 구분하기 위해서 우리는 ‘너는 1학년1반홍길동이니?’라고 물어볼 것이다. 이게 바로 math.sin(1.0)의 개념이다. 앞에 math가 1학년1반의 개념이고 sin이 홍길동의 개념이다. 누군가가 sin이라는 함수를 정의했다고 하자. 그런데 그게 수학에서 말하는 sin값을 구하는 것은 아니고 다른 일을 하는 함수였다. 그리고 그걸 다른 사람이 쓸 수 있도록 공유했다고 하자. 수학에서 쓰는 sin과 다른 일을 하는 별도로 정의된 함수인 sin을 구분하기 위해서 각각 sin을 정의한 모듈이나 패키지의 이름을 앞에 써준다.

 

모듈과 패키지는 파이썬의 강력한 기능을 받쳐주는 중요한 기능이다. 다음 시간에는 공개된 모듈이나 패키지를 내 컴퓨터에 설치하고 사용하는 방법을 알아보겠다.

 

 

 

 



  추천하기   목록보기

Copyright 1999-2023 Zeroboard / skin by zero
구조설계의 미래를 준비하는 모임 [구조설계미래포럼]