[References]
http://pythonstudy.xyz
클래스(Class)
Python은 객체지향 프로그래밍(OOP)을 기본적으로 지원하고 있다. Python에서 Class를 만들기 위해서는 아래와 같이 "class Class명"을 사용하여 Class를 정의한다. Class명은 PEP 8 Coding Convention에 Guide 된 대로 각 단어의 첫 문자를 대문자로 하는 Cap Words 방식으로 명명한다. 아래 예제는 MyClass라는 Class를 정의한 것으로 pass를 사용하여 Class Member가 모두 비어 있음을 나타낸 가장 간단한 빈 Class이다.
class MyClass:
pass
1. Class Member
Class는 Method, 속성(Property), Class 변수(Class Variable), 생성자(Constructor), 소멸자(Destructor) 등의 여러 Member들을 가질 수 있다.
2. Method
Method는 Class의 행위를 표현하는 것으로 Class 내의 함수로 볼 수 있다. 즉, Method는 해당 Class와 관련된 어떤 행위를 표현하는 함수인데, 함수와 다르게 항상 첫 번째 Parameter로 해당 Class 객체를 나타내는 "self"를 갖는다. 아래 예제에서 calcArea()가 Method에 해당된다. Method는 여러 Parameter를 가질 수 있지만, 첫 번째 Parameter는 항상 self를 갖는다.
class Rectangle:
# Class 변수
count = 0
# 생성자(constructor)
def __init__(self, width, height):
# self.* : Instance변수
self.width = width
self.height = height
Rectangle.count += 1
# Method
def calcArea(self):
area = self.width * self.height
return area
3. Class 변수
Class 정의에서 Method 밖에 존재하는 변수를 Class 변수(Class Variable)라 하는데, 이는 해당 Class를 사용하는 모두에게 공용으로 사용되는 변수이다. Class 변수는 (Class 내․외부에서) "Class명.변수명" 혹은 (Class 외부에서) "Instance변수명.변수명"으로 access 할 수 있다. 위의 예제에서 count는 Class 변수로서 Class 내부에서는 Rectangle.count와 같이 access 할 수 있다.
4. Instance 변수
Class 정의에서 Method 안에 사용되면서 "self.변수명"처럼 사용되는 변수를 Instance 변수(instance variable)라 하는데, 이는 각 객체별로 서로 다른 값을 갖는 변수이다. Instance 변수는 Class 내부에서는 self.width와 같이 "self."을 사용하여 access 하고, Class 밖에서는 "객체 변수.Instance 변수"와 같이 access 한다.
Python은 다른 언어에서 흔히 사용하는 public, protected, private 등의 접근 제한자(Access Modifier)를 갖지 않는다. 기본적으로 모든 attribute가 public이라고 할 수 있다. 만약 특정 변수명이나 Method를 private으로 만들어야 한다면 두개의 밑줄(__)을 그 이름 앞에 붙이면 된다.
def __init__(self, width, height):
self.width = width
self.height = height
# private 변수 __area
self.__area = width * height
# private Method
def __internalRun(self):
pass
5. 생성자
Class로부터 새 객체를 생성할 때마다 실행되는 특별한 Method로 __init__() 이라는 Method가 있는데, 이를 흔히 Class 생성자(constructor)라 부른다. (Python에서 두개의 밑줄 (__) 시작하고 두개의 밑줄로 끝나는 레이블은 보통 특별한 의미를 갖는다.) 생성자는 Class로부터 객체를 만들 때, Instance 변수를 초기화하거나 객체의 초기 상태를 만들기 위한 문장들을 실행하는 곳이다.
위의 예제에서는 width와 height를 Instance 변수에 할당하여 계속 객체에서 사용할 수 있도록 준비하고 있다.
6. 그 밖의 특별한 Method들
Python에는 생성자 이외에도 객체가 소멸될 때 실행되는 소멸자(__del__) Method, 두 개의 객체를 ( + 기호로) 더하는 __add__ Method, 두 개의 객체를 ( - 기호로) 빼는 __sub__ Method, 두 개의 객체를 비교하는 __cmp__ Method, 문자열로 객체를 표현할 때 사용하는 __str__ Method 등 매우 많은 특별한 Method들이 있다.
def __add__(self, other):
obj = Rectangle(self.width + other.width, self.height + other.height)
return obj
# 사용 예
r1 = Rectangle(10, 5)
r2 = Rectangle(20, 15)
# __add__()가 호출됨
r3 = r1 + r2
7. 객체의 생성과 사용
Class를 사용하기 위해서는 먼저 Class로부터 객체(Object)를 생성해야 한다. Python에서 객체를 생성하기 위해서는 "객체 변수명 = Class명()"과 같이 Class명을 함수 호출하는 것처럼 사용하면 된다. 만약, __init__() 생성자가 있고, 그곳에 입력 Parameter들이 지정되어 있다면, "Class명(입력Parameter들)"과 같이 Parameter를 괄호 안에 전달한다. 이렇게 전달된 Parameter들은 생성자에서 사용된다. 아래 예제를 보면, Rectangle Class로부터 r이라는 객체를 생성하고 있는데, Rectangle(2, 3)과 같이 2개의 Parameter를 전달하고 있다. 이는 Rectangle 생성자에서 각각 width와 height Instance 변수를 초기화하는데 사용되고 있다.
# 객체 생성
r = Rectangle(2, 3)
# Method 호출
area = r.calcArea()
print("area = ", area)
# Instance 변수 access
r.width = 10
print("width = ", r.width)
# Class 변수 access
print(r.count)
print(Rectangle.count)
Class로부터 생성된 객체(Object)로부터 Class Member들을 호출하거나 access 할 수 있다. Method는 "객체 변수.Method명()"과 같이 호출할 수 있는데, 위의 예제에선 r.calcArea()이 Method 호출에 해당된다. Instance 변수는 "객체 변수.Instance 변수"로 표현되며, 값을 읽거나 변경하는 일이 가능하다. 위의 예제 r.width = 10은 "Instance 변수" width에 새 값을 할당하는 예이다. 또한, Class 변수는 "객체 변수.Class 변수" 혹은 "Class명.Class 변수"를 사용하여 access 할 수 있는데, 위의 예제에서 r.count 혹은 Rectangle.count로 access 하는 예를 보이고 있다.
8. Class 상속과 다형성
Python은 객체지향 프로그래밍의 상속(Inheritance)을 지원하고 있다. Class를 상속 받기 위해서는 파생 Class(자식 Class)에서 Class명 뒤에 Base Class(부모 Class) 이름을 괄호와 함께 넣어 주면 된다. 즉, 아래 예제에서 Dog Class는 Animal Class로부터 파생된 파생 Class이며, Duck Class도 역시 Animal Base Class로부터 파생되고 있다. (주: Python은 복수의 부모 Class로부터 상속 받을 수 있는 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")
파생 Class는 Base Class의 Member들을 호출하거나 사용할 수 있으며, 물론 파생 Class 자신의 Member들을 사용할 수 있다.
# 부모 Class의 생성자
dog = Dog("doggy")
# 부모 Class의 Instance 변수
n = dog.name
# 부모 Class의 Method
dog.move()
# 파생 Class의 Member
dog.speak()
Python은 객체지향 프로그래밍의 다형성(Polymorphism)을 지원하고 있다. 아래 예제는 animals 라는 List에 Dog 객체와 Duck 객체를 넣고 이들의 speak() Method를 호출한 예이다. Code 실행 결과를 보면 객체의 타입에 따라 서로 다른 speak() Method가 호출됨을 알 수 있다.
def animalSpeak(animal):
animal.speak()
animals = [Dog('doggy'), Duck('duck')]
for a in animals:
animalSpeak(a)