클래스

1. 클래스

파이썬은 객체지향 프로그래밍(OOP)를 기본적으로 지원하고 있다. 파이썬에서 클래스를 만들기 위해서는 아래와 같이 "class 클래스명" 을 사용하여 클래스를 정의한다. 클래스명은 PEP 8 Coding Convention에 가이드된 대로 각 단어의 첫 문자를 대문자로 하는 CapWords 방식으로 명명한다. 아래 예제는 MyClass라는 클래스를 정의한 것으로 pass를 사용하여 클래스 멤버가 모두 비어 있음을 나타낸 가장 간단한 빈 클래스이다.

class MyClass:
	pass

2. 클래스 멤버

클래스는 메서드(method), 속성(property), 클래스 변수 (class variable), 초기자(initializer), 소멸자(destructor) 등의 여러 맴버들을 가질 수 있다.

메서드

메서드는 클래스의 행위를 표현하는 것으로 클래스 내의 함수로 볼 수 있다. 즉, 메서드는 해당 클래스와 관련된 어떤 행위를 표현하는 함수인데, 함수와 다르게 항상 첫번째 파라미터로 해당 클래스 객체를 나타내는 "self" 를 갖는다. 아래 예제에서 calcArea()가 메서드에 해당된다. 메서드는 여러 파라미터를 가질 수 있지만, 첫번째 파라미터는 항상 self 를 갖는다.

class Rectangle:
    count = 0  # 클래스 변수

    # 초기자(initializer)
    def __init__(self, width, height):
        # self.* : 인스턴스변수
        self.width = width
        self.height = height
        Rectangle.count += 1

    # 메서드
    def calcArea(self):
        area = self.width * self.height
        return area
클래스 변수

클래스 정의에서 메서드 밖에 존재하는 변수를 클래스 변수(class variable)라 하는데, 이는 해당 클래스를 사용하는 모두에게 공용으로 사용되는 변수이다. 클래스 변수는 "클래스명.변수명" (클래스 내외부에서) 혹은 "인스턴스변수명.변수명" (클래스 외부에서) 으로 엑세스 할 수 있다. 위의 예제에서 count는 클래스변수로서 클래스 내부에서는 Rectangle.count 과 같이 엑세스할 수 있다.

인스턴스 변수

클래스 정의에서 메서드 안에서 사용되면서 "self.변수명"처럼 사용되는 변수를 인스턴스 변수(instance variable)라 하는데, 이는 각 객체별로 서로 다른 값을 갖는 변수이다. 인스턴스 변수는 클래스 내부에서는 self.width 과 같이 "self." 을 사용하여 엑세스하고, 클래스 밖에서는 "객체변수.인스턴스변수"와 같이 엑세스 한다.

Python은 다른 언어에서 흔히 사용하는 public, protected, private 등의 접근 제한자 (Access Modifier)를 갖지 않는다. 기본적으로 모든 멤버가 public이라고 할 수 있다. Python 코딩 관례(Convention)상 내부적으로만 사용하는 변수 혹은 메서드는 그 이름 앞에 하나의 밑줄(_) 을 붙인다. 하지만 이는 코딩 관례에 따른 것일 뿐 실제 밑줄 하나를 사용한 멤버는 public 이므로 필요하면 외부에서 엑세스할 수 있다.
만약 특정 변수명이나 메서드를 private으로 만들어야 한다면 두개의 밑줄(__)을 그 이름 앞에 붙이면 된다.

def __init__(self, width, height):
	self.width = width
	self.height = height

	# private 변수 __area
	self.__area = width * height

# private 메서드
def __internalRun(self):
	pass
Initializer (초기자)

클래스로부터 새 객체를 생성할 때마다 실행되는 특별한 메서드로 __init__() 이라는 메서드가 있는데, 이를 흔히 클래스 Initializer 라 부른다 (주: 파이썬에서 두개의 밑줄 (__) 시작하고 두개의 밑줄로 끝나는 레이블은 보통 특별한 의미를 갖는다). Initializer는 클래스로부터 객체를 만들 때, 인스턴스 변수를 초기화하거나 객체의 초기상태를 만들기 위한 문장들을 실행하는 곳이다. 위의 예제에서는 width와 height를 인스턴스변수에 할당하여 계속 객체에서 사용할 수 있도록 준비하고 있다.
(주: Python의 Initializer는 C#/C++/Java 등에 일컫는 생성자(Constructor)와 약간 다르다. Python에서 클래스 생성자(Constructor)는 런타임 엔진에 의해 실행되며, 만약 Initializer가 있으면 생성자가 Initializer를 호출하여 객체의 변수 등을 초기화한다.).

그 밖의 특별한 메서드들

파이썬에는 Initializer 이외에도 객체가 소멸될 때 (Garbage Collection 될 때) 실행되는 소멸자(__del__) 메서드, 두 개의 객체를 ( + 기호로) 더하는 __add__ 메서드, 두 개의 객체를 ( - 기호로) 빼는 __sub__ 메서드, 두 개의 객체를 비교하는 __cmp__ 메서드, 문자열로 객체를 표현할 때 사용하는 __str__ 메서드 등 매우 많은 특별한 메서드들이 있다.

def __add__(self, other):
	obj = Rectangle(self.width + other.width, self.height + other.height)
	return obj

# 사용 예
r1 = Rectangle(10, 5)
r2 = Rectangle(20, 15)
r3 = r1 + r2  # __add__()가 호출됨

3. 객체의 생성과 사용

클래스를 사용하기 위해서는 먼저 클래스로부터 객체(Object)를 생성해야 한다. 파이썬에서 객체를 생성하기 위해서는 "객체변수명 = 클래스명()"과 같이 클래스명을 함수 호출하는 것처럼 사용하면 된다. 만약 __init__() 함수가 있고, 그곳에 입력 파라미터들이 지정되어 있다면, "클래스명(입력파라미터들)"과 같이 파라미터를 괄호 안에 전달한다. 이렇게 전달된 파라미터들은 Initializer 에서 사용된다.

아래 예제를 보면, Rectangle 클래스로부터 r 이라는 객체를 생성 하고 있는데, Rectangle(2, 3)와 같이 2개의 파라미터를 전달하고 있다. 이는 Rectangle 초기자에서 각각 width와 height 인스턴스 변수를 초기화하는데 사용된다.

# 객체 생성
r = Rectangle(2, 3)

# 메서드 호출
area = r.calcArea()
print("area = ", area)

# 인스턴스 변수 엑세스
r.width = 10
print("width = ", r.width)

# 클래스 변수 엑세스
print(r.count)
print(Rectangle.count)

클래스로부터 생성된 객체(Object)로부터 클래스 멤버들을 호출하거나 엑세스할 수 있다. 메서드는 "객체변수.메서드명()"과 같이 호출할 수 있는데, 위의 예제에선 r.calcArea() 이 메서드 호출에 해당된다. 인스턴스 변수는 "객체변수.인스턴스변수" 으로 표현되며, 값을 읽거나 변경하는 일이 가능하다. 위의 예제 r.width = 10 은 인스턴스변수 width 에 새 값을 할당하는 예이다. 또한, 클래스 변수는 "객체변수.클래스변수" 혹은 "클래스명.클래스변수" 를 사용하여 엑세스할 수 있는데, 위의 예제에서 r.count 혹은 Rectangle.count 으로 엑세스 하는 예를 보이고 있다.

4. 클래스 상속과 다형성

파이썬은 객체지향 프로그래밍의 상속(Inheritance)을 지원하고 있다. 클래스를 상속 받기 위해서는 파생클래스(자식클래스)에서 클래스명 뒤에 베이스클래스(부모클래스) 이름을 괄호와 함께 넣어 주면 된다. 즉, 아래 예제에서 Dog 클래스는 Animal 클래스로부터 파생된 파생클래스이며, Duck 클래스도 역시 Animal 베이스클래스로부터 파생되고 있다. (주: 파이썬은 복수의 부모클래스로부터 상속 받을 수 있는 Multiple Inheritance를 지원하고 있다.)

class Animal:
    def __init__(self, name):
        self.name = name
    def move(self):
        print("move")
    def speak(self):
        pass

class Dog (Animal):
    def speak(self):
        print("bark")

class Duck (Animal):
    def speak(self):
        print("quack")

파생클래스는 베이스클래스의 멤버들을 호출하거나 사용할 수 있으며, 물론 파생클래스 자신의 멤버들을 사용할 수 있다.

dog = Dog("doggy") # 부모클래스의 생성자
n = dog.name # 부모클래스의 인스턴스변수
dog.move()   # 부모클래스의 메서드
dog.speak()  # 파생클래스의 멤버

파이썬은 객체지향 프로그래밍의 다형성(Polymorphism)을 또한 지원하고 있다. 아래 예제는 animals 라는 리스트에 Dog 객체와 Duck 객체를 넣고 이들의 speak() 메서드를 호출한 예이다. 코드 실행 결과를 보면 객체의 타입에 따라 서로 다른 speak() 메서드가 호출됨을 알 수 있다.

def animalSpeak(animal):
    animal.speak()

animals = [Dog('doggy'), Duck('duck')]
for a in animals:
    animalSpeak(a)
본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.