-
Notifications
You must be signed in to change notification settings - Fork 0
2.11. 내용정리: 11일차
- 파이썬에서 모듈은 하나의
.py
파일이다. -
패키지(Packages) 란, 접근 연산자 도트(
.
)를 사용하여 파이썬 모듈을 계층적(디렉터리 구조)으로 관리할 수 있도록 해준다. - 예를 들어, 모듈 이름이
A.B
인 경우에A
는 패키지 이름이 되고,B
는 패키지A
의 모듈B
가 된다.
- 간단한 파이썬 프로그램이 아니라면 패키지 구조로 파이썬 프로그램을 만드는 것이 공동 작업이나 유지 보수 등 여러 면에서 유리하다.
- 또한, 패키지 구조로 모듈을 만들면 다른 모듈과 이름이 겹치더라도 더 안전하게 사용할 수 있다.
패키지를 만드는 방법은 다음과 같다.
- 자신이 원하는 패키지명으로 디렉터리를 생성한다.
-
__init__.py
파일을 생성한다. - 패키지 안에 또다른 패키지를 생성하고 싶다면, 자신이 원하는 패키지명으로 서브(하위) 디렉터리를 생성한다.
- 생성했던 서브 디렉터리 안에
__init__.py
파일을 생성한다. - 자신이 만들고자 하는 모듈을 만든다.
예를 들어, 다음과 같이 my_package
라는 모듈을 만든다고 가정해보자.
-
my_package
라는 디렉터리를 생성한다. -
my_package
라는 패키지 안에A
,B
라는 서브 디렉터리를 생성한다. - 패키지
A
안에test1
과test2
라는 모듈을 생성한다. - 패키지
B
안에test3
와test4
라는 모듈을 생성한다.
위의 내용을 구조로 나타내면 다음과 같다.
my_package/
__init__.py
A/
__init__.py
test1.py
test2.py
B/
__init__.py
test3.py
test4.py
-
__init__.py
파일은 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 한다. - 만약 위에서 든 예시의 경우, 패키지
A
와B
패키지에 포함된 디렉터리에__init__.py
파일이 없다면 패키지로 인식되지 않는다. - 즉,
__init__.py
라는 파일은 파이썬 패키지를 인식시켜주는 파일이다. - 주로 패키지가
import
될 때 초기화하는 작업을 하는 용도로 사용된다.
만약 디렉터리 B
의 test3.py
모듈에서 디렉터리 A
의 test1.py
모듈을 사용하고 싶다면 다음과 같이 test3.py
를 수정하면 가능하다.
# test3.py
from my_package.A import test1
위 예제처럼 from my_package.A import test1
을 입력해 전체 경로를 사용하여 import
할 수도 있지만 다음과 같이 relative 하게 import
하는 것도 가능하다.
# test3.py
from ..A import test1
-
from my_package.A import test1
가from ..A import test1
로 변경되었다. - 여기에서
..
은test1.py
파일의 상위(부모) 디렉터리를 의미한다. - 따라서
test1.py
파일의 상위 디렉터리는A
이므로 위와 같은import
가 가능한 것이다.
※
test1.py
파일의 현재 디렉터리는A
이고, 상위 디렉터리는my_package
이다.
relative한 접근자에는 다음과 같은 것이 있다.
-
..
: 상위(부모) 디렉터리 -
.
: 현재 디렉터리
-
몽키 패치란, 프로그램이 내부 프로그램을 로컬에서 잠시 다른 기능을 수행하도록 수정하거나 확장하도록 하는 방법이다.
- 요약하자면, 프로그램을 확장하거나, 로컬 시스템 소프트웨어를 지원하고 수정하는 방법이다.
- 또한, 오직 실행중인 프로그램의 인스턴스에 영향을 미친다.
- 이는 로컬이므로, 프로그램 동작 시(즉, 런타임 도중)에만 영향을 주는 방식이다.
- 다시 말해, 런타임 상에서 함수, 메서드, 속성을 바꾸는 것을 의미한다.
- 소스 코드가 없는 서드 파티 제품을 사용하는 중 기능을 변경하거나 확장을 위해 사용한다.
- 런타임 실행중 메모리 상의 오브젝트에 적용된다.
- 이름의 유래는 원래 게릴라 패치였다고 한다.
- 게릴라란, 집단에 속하지 않고 개별적인 행위를 하는 사람 또는 단체라는 의미로 그냥 개인 플레이라고 생각하면 된다.
- 게릴라 패치라는 이름 그대로 특정 기능을 위해 개별적인 행위를 해서 이러한 이름이 붙여졌을 것이다.
- 게릴라패치가 몽키패치가 된 건 발음의 유사성에 있다.
- 즉, 게릴라(Guerrilla) -> 고릴라(Gorilla) -> 원숭이(Monkey) 순으로 변화한 것이다.
- 게릴라 패치에서 발음의 유사한 고릴라패치로 변했는데 고릴라 패치라고 하면 너무 크고 거대한 패치라고 들리는 문제점이 있었다고 한다.
- 실은 런타임에서 돌아가는 상대적으로 자그마한 변화였는데도 불구하고 말이다.
- 그래서 이번에는 발음의 유사성보단 종의 '유사성 + 귀여움'으로 인해 원숭이로 바뀌게 되었다고 한다.
다음과 같이 test
라는 모듈이 있고, hello
라는 함수가 정의되어 있다고 가정하자.
# test.py
def hello():
print('Hello, Python!')
그리고 이 모듈을 import
한 모듈 test2
를 새롭게 생성한다.
# test2.py
import test
그 다음 기존에 모듈 test
에 정의한 함수 hello
를 다시 재정의한다.
#test2.py
import test
def hello():
print('Hi, Python!')
test.hello
를 재정의한 함수 hello
로 변경해준다.
# test2.py
import test
def hello():
print('Hi, Python!')
test.hello = hello
즉, 모듈 test
를 import
한 후에 모듈 test2
도 같이 import
하게 된다면 test2
에서 재정의한 함수 hello
로 변경될 것이다.
import test
import test2
# 'Hi, Python!'이 출력된다.
test.hello()
클래스 역시 재정의하는 것이 가능하다.
# test.py
class MyClass:
def hello(self):
print('Hello, Python!')
위의 test
모듈에서 정의한 MyClass
를 새롭게 생성한 모듈 test2
의 클래스 MyClass2
로 변경시킨다.
# test2.py
import test
class MyClass2:
def hello(self):
print('Hi, Python!')
test.MyClass = MyClass2
그리고 아래의 예시처럼 모듈 test
와 test2
를 import
해서 hello
메서드를 호출해본다.
import test
import test2
m = test.MyClass()
m.hello()