학습 목표
- 클래스, 모듈, 패키지에 대해 설명할 수 있다
학습 내용
클래스
클래스의 정의
클래스는 객체를 만들어내기 위한 일종의 틀이다. 객체는 클래스에 정의된 내용대로 만들어지며, 각 객체는 서로 독립적으로 존재한다.
클래스는 보통 다음과 같은 형식으로 정의된다.
class 클래스이름: # 클래스 내용
클래스 이름은 보통 대문자로 시작하며, 각 단어의 첫 글자는 대문자로 적는 것이 관례이다. 클래스 내용은 필요에 따라 다양한 속성(attribute)과 메서드(method)로 구성된다.
객체
객체는 클래스를 이용하여 만들어낸 것으로, 해당 클래스의 인스턴스(instance)라고도 부른다. 객체는 클래스에 정의된 속성과 메서드를 가지며, 서로 다른 객체는 서로 다른 속성 값을 가질 수 있다.
객체는 다음과 같은 형식으로 생성된다.
객체이름 = 클래스이름()
클래스 이름 다음에 괄호를 붙이면 해당 클래스의 객체가 생성된다. 생성된 객체는 객체 이름에 할당된다.


해당 예시를 보면 객체 cal1 과 cal2가 서로 독립된 결과를 print하고 있음을 알 수 있다.
해당 클래스의 메소드를 추가하여 간단한 사칙연산이 가능한 class를 생성해보자
class Cal:
# 여기서 self는 해당 클래스로 생성된 객체의 값을 뜻하므로
# 따로 인수를 전달해주지 않아도 된다.
def setdata(self, first, second):
self.first = first
self.second = second
def add(self):
result = self.first + self.second
return result
def sub(self):
result = self.first - self.second
return result
def mul(self):
result = self.first * self.second
return result
def div(self):
result = self.first / self.second
return result
cal1 = Cal()
cal1.setdata(4,3)
print(cal1.add())
생성자
클래스를 이용하여 객체를 만들 때, 객체가 생성될 때 자동으로 호출되는 메소드를 생성자(constructor)라고 한다.
생성자는 클래스 내부에 __init__
이라는 이름으로 정의되며, 객체가 생성될 때 자동으로 호출된다.
생성자를 이용하여 객체를 초기화하는 작업을 수행할 수 있다.
class Cal:
def __init__(self, first, second):
# 객체 초기화
self.first = first
self.second = second
__init__
메소드의 첫 번째 매개변수는 self
이다. self
는 해당 클래스의 객체 그 자체를 의미한다.
객체를 생성할 때 입력한 매개변수는 __init__
메소드의 두 번째 매개변수부터 순서대로 전달된다.
class Cal:
def setdata(self, first, second):
self.first = first
self.second = second
def add(self):
result = self.first + self.second
return result
cal1 = Calculator(10, 20)
print(cal1.add())
위 코드에서는 Calculator
클래스에 __init__
메소드를 추가하여 객체 생성 시 초기화를 할 수 있도록 하였다.
Calculator
클래스에서는 first
와 second
라는 두 개의 매개변수를 받아서 객체를 초기화하고 있다.
객체를 생성할 때는 Calculator(10, 20)
과 같은 형태로 입력하면 된다.
객체 cal1
은 Calculator
클래스의 인스턴스로 생성된 것이며, add
메소드를 호출하여 30
을 출력하게 된다.
클래스 상속
클래스 상속을 이용하면 이미 만들어진 클래스의 내용을 그대로 물려받아 새로운 클래스를 만들 수 있다. 이 때 물려받은 클래스를 부모 클래스(parent class)라고 하고, 새로 만든 클래스를 자식 클래스(child class) 또는 파생 클래스(derived class)라고 한다.
부모 클래스에서 정의된 모든 속성과 메소드를 자식 클래스에서 그대로 사용할 수 있으며, 자식 클래스에서 필요에 따라 속성이나 메소드를 추가하거나 변경할 수도 있다.
아래 코드는 Cal
클래스를 상속받아 ImprovedCal
클래스를 정의한 예시이다.
class ImprovedCal(Cal):
def pow(self):
result = self.first ** self.second
return result
def div(self):
if self.second == 0:
return 0
else:
return self.first / self.second
ImprovedCal
클래스는 Cal
클래스를 상속받아서 만들어졌다. Cal
클래스에는 add
, sub
, mul
, div
메소드가 있으며, ImprovedCal
클래스에서는 pow
메소드를 추가하고 div
메소드를 변경하여 0으로 나누는 경우에는 0을 반환하도록 하였다.
여기서 div의 예외처리를 진행했으며 이를 오버라이딩 이라고 한다.
상속받은 메소드를 그대로 사용하거나 변경하려면 다음과 같은 형식으로 호출하면 된다.
cal = ImprovedCal(4, 2)
print(cal.add())
위 코드에서 ImprovedCal
클래스의 객체 cal
을 생성하고, add
메소드를 호출하여 6
을 출력하게 된다.
클래스 변수
클래스 변수(class variable)는 클래스 내부에서 정의된 변수로서, 해당 클래스의 모든 객체에서 공유된다. 클래스 변수는 클래스 이름으로 호출할 수 있으며, 객체 이름으로도 호출할 수 있다.
클래스 변수는 다음과 같이 정의된다.
class 클래스이름: 클래스변수 = 값
객체를 통해 클래스 변수에 접근할 때는 다음과 같이 접근할 수 있다.
객체이름.클래스변수
클래스 변수는 클래스의 모든 객체에서 공유되기 때문에, 한 객체에서 클래스 변수의 값을 변경하면 그 값은 다른 객체에서도 변경된 상태로 유지된다.
class Car:
count = 0
def __init__(self, name):
self.name = name
Car.count += 1
car1 = Car("아반떼")
car2 = Car("소나타")
print(Car.count)
위 코드에서는 Car
클래스에 count
라는 클래스 변수를 정의하고, 객체가 생성될 때마다 count
변수를 1 증가시키고 있다.
객체 car1
과 car2
를 생성하면서 count
변수를 1씩 증가시켰으므로, print
함수를 호출하여 2
를 출력하게 된다.
모듈
모듈 불러오기
파이썬 모듈(Module)은 함수나 변수, 클래스들을 모아놓은 파일이다. 다른 파이썬 프로그램에서 불러와 사용할 수 있도록 만들어진 것이며, 작성한 모듈은 다른 파이썬 프로그램에서도 불러와 사용할 수 있어 재사용성이 높다. 파이썬에는 이미 많은 표준 모듈들이 존재하며, 개발자가 필요한 모듈을 직접 만들어서 사용할 수도 있다.
모듈을 사용하기 위해서는 import
문을 사용하여 해당 모듈을 불러와야 한다. 모듈을 불러오는 방법에는 import 모듈이름
또는 from 모듈이름 import 변수이름(또는 함수이름, 클래스이름)
등이 있다.
# 모듈 불러오기
import math
# 모듈 내 함수 사용하기
print(math.sqrt(4)) # 2.0
위 코드에서는 math
모듈을 불러와, sqrt
함수를 사용하여 4의 제곱근을 계산하고 있다. import
문을 통해 모듈을 불러오면, 해당 모듈 내의 함수나 변수 등을 사용할 수 있다.
모듈 만들기
모듈 내에서는 함수, 변수, 클래스 등을 정의할 수 있다. 다음은 example
모듈을 정의하는 예시이다.
# example 모듈 정의하기
def add(a, b):
return a + b
def sub(a, b):
return a - b
class Calculator:
def __init__(self):
self.result = 0
def add(self, num):
self.result += num
return self.result
def sub(self, num):
self.result -= num
return self.result
위 코드에서는 add
함수와 sub
함수, 그리고 Calculator
클래스를 정의하여 example
모듈로 만들었다. 이렇게 만들어진 example
모듈은 다른 파이썬 프로그램에서 import
문을 사용하여 불러와서 사용할 수 있다.
# example 모듈 사용하기
import example
print(example.add(3,4)) # 7
print(example.sub(4,2)) # 2
cal = example.Calculator()
print(cal.add(3)) # 3
print(cal.add(4)) # 7
print(cal.sub(2)) # 5
위 코드에서는 example
모듈을 불러와서, add
함수와 sub
함수, 그리고 Calculator
클래스를 사용하고 있다. 이렇게 모듈을 사용하면, 다른 파이썬 프로그램에서도 같은 함수나 클래스를 다시 작성하지 않아도 되어 재사용성이 높아진다.
if name == “__main__” : 의 의미
__name__
변수는 파이썬에서 내부적으로 사용되는 특별한 변수이다. 이 변수는 현재 모듈의 이름을 나타내며, 현재 모듈이 직접 실행되는 경우에는 __main__
값을 갖게 된다.
따라서 if __name__ == "__main__":
구문은 현재 모듈이 직접 실행되는 경우에만 실행되도록 하는 역할을 수행한다. 이 구문은 일반적으로 해당 모듈이 직접 실행되었을 때 수행해야 하는 코드를 작성하는 데 사용된다.
예를 들어, example.py
모듈에서 if __name__ == "__main__":
구문을 사용하여 해당 모듈이 직접 실행될 때만 실행되는 코드를 작성할 수 있다. 이렇게 작성된 코드는 다른 파이썬 프로그램에서 이 모듈을 불러와서 사용할 때는 실행되지 않으며, 해당 모듈을 직접 실행할 때만 실행되게 된다.
패키지
패키지(Package)는 파이썬에서 모듈들을 관리하기 위한 디렉토리 구조를 말한다. 모듈들을 묶어서 관리함으로써, 이름이 겹치는 모듈들을 구분할 수 있고, 모듈들을 계층적으로 구조화하여 관리할 수 있다.
패키지는 다음과 같은 구조를 가진다.
example_package/
__init__.py
module1.py
module2.py
...
example_package
: 패키지 이름
__init__.py
: 패키지 초기화 파일
module1.py
,module2.py
: 패키지 내에 포함된 모듈들
모듈을 패키지로 묶어서 관리하면, 다른 프로그램에서 해당 패키지를 불러와 사용할 수 있다. 패키지를 불러올 때는 다음과 같이 import
문을 사용한다.
import example_package.module1
import example_package.module2
또는 다음과 같이 from
키워드를 사용하여 모듈을 직접 불러올 수도 있다.
from example_package import module1, module2
패키지를 사용하면, 모듈들을 계층적으로 구조화하여 관리할 수 있다. 예를 들어, 다음과 같은 패키지 구조를 가진다면,
example_package/
__init__.py
calculator/
__init__.py
add.py
sub.py
converter/
__init__.py
length.py
weight.py
calculator
패키지 내에는 add
모듈과 sub
모듈이, converter
패키지 내에는 length
모듈과 weight
모듈이 각각 포함되어 있다. 이렇게 패키지를 계층적으로 구조화하면, 모듈들을 더욱 체계적으로 관리할 수 있다.
relative 패키지
상대 패키지(Relative package)는 패키지 내에서 모듈을 상대적인 경로로 참조할 수 있도록 하는 것을 말한다. 일반적으로 패키지 내에서 모듈을 불러올 때는 절대 경로를 사용하여 불러오는데, 이 경우 패키지의 위치가 변경될 경우 모듈을 불러오는 코드도 변경해야 하므로 불편하다. 따라서 상대 패키지를 사용하면 패키지 내부의 모듈을 상대적인 경로로 참조할 수 있어 패키지의 위치가 변경되더라도 모듈을 불러오는 코드를 변경할 필요가 없다.