Class - 2

김상우·2022년 3월 17일
0

Python

목록 보기
9/14
post-thumbnail

완전 기초부터 시작하는 파이썬

Class 구조 만들기

이전 게시물의 예제를 바탕으로 구조물 하나씩 만들기

  • 클래스 생성
class calculator:
	pass

아무런 기능이 없는 클래스를 먼저 생성한다.

>>> a = calculator()
>>> type(a)
<class '__main__.calculator'>

a라는 객체를 만든 후 콘솔에서 생성된 객체 a의 타입을 알아본다. 확인해본 결과 calculator 클래스에 객체라는 것을 알 수 있다.
그러나 이 a라는 객체는 아무런 기능을 하지 못하기 때문에 계산기의 사칙연산 기능을 할 수 있는 객체를 만들어야 한다.

  • 함수 생성
class calculator:
    def setdata(self, first, second):
        self.first = first
        self.second = second

pass 문장을 삭제 후 setdata 함수를 만들어 메서드(method)를 생성했다.

>>> a = caculator()
>>> a.setdata(4, 2)
>>> print(a.first)
4
>>> print(a.second)
2

객체 a를 생성하고 first에 4, second에 2를 호출하면 setdata 메서드에 매개변수 first와 second는 각각의 값이 전달되어 self.first = 4, self.second = 2로 수행된다.
이를 확인하기 위해 콘솔에서 확인해보면 a.first = 4, a.second = 2가 저장되었음을 확인할 수 있다.

>>> a = calculator()
>>> b = calculator()
>>> a.setdata(4, 2)
>>> b.setdata(3, 7)
>>> id(a.first)
140316044880272
>>> id(b.first)
140316044880240

클래스로 만든 객체의 여러개의 객체변수를 지정해도 각각의 객체에 독립적인 값이 저장된다는 점을 id()로 확인할 수 있다.

  • 합연산 함수 생성
class calculator:
    def setdata(self, first, second):
        self.first = first
        self.second = second
    
    def add(self):
        result = self.first + self.second
        return result 

위에서 작성한 클래스에 합연산 기능을 하는 add 메서드를 추가한 모습이다.

class calculator:
    def setdata(self, first, second):
        self.first = first
        self.second = second
    
    def add(self):
        result = self.first + self.second
        return result
        
a = calculator()
b = calculator()
a.setdata(4, 2)
b.setdata(3, 7)

print(a.add())
print(b.add())

지금까지 작성한 결과를 조립해보면 위의 코드로 나타낼 수 있다.
객체 a의 first와 second는 4, 2가 저장되고 객체 b의 first와 second에는 3, 7이 저장된다.
추가로 작성한 add() 메서드를 호출하여 저장된 값으로 add메서드를 수행하여 결과를 나타낸다.

6
10

  • 뺄셈, 곱셈, 나눗셈 메서드 생성
    사칙 연산을 할 수 있는 프로그램을 만들기 위해 나머지 연산방법도 추가할 수 있다.
class calculator:
    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
    
a = calculator()
b = calculator()
a.setdata(4, 2)
b.setdata(3, 7)

print(a.add())
print(a.sub())
print(a.mul())
print(a.div())

print(b.add())
print(b.sub())
print(b.mul())
print(b.div())

사칙연산을 추가한 코드는 다음과 같으며 객체에 따라 계산되어 출력되는 값은 아래와 같다.

6
2
8
2.0
10
-4
21
0.42857142857142855

  • Constructor(생성자)
    지금까지 작성한 코드에서는 객체에 초기값을 설정해야할 필요가 있기 때문에 setdata처럼 메서드를 호출해야한다. 그러나 그보다 안전한 방법은 생성자를 구현하는것이 좋다.
    파이썬 메서드 이름으로 '__init__'를 사용하면 이 메서드는 생성자가 된다.
def __init__(self, first, second):
        self.first = first
        self.second = second

__init__ 메서드는 메서드의 이름만 다르고 setdata와 동일하지만 이름자체가 __init__ 으로 지정했기 때문에 생성자로 인식되어 객체가 생성되는 시점에 자동으로 호출되는 차이가 있다.

class calculator:
    def __init__(self, first, second):
        self.first = first
        self.second = second
        
    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
    
a = calculator(4, 2)
b = calculator(3, 7)

print(a.add())
print(a.sub())
print(a.mul())
print(a.div())

print(b.add())
print(b.sub())
print(b.mul())
print(b.div())

생성자를 추가하여 수정된 코드는 위와 같으며 생성자가 없는 코드와 비교해 setdata를 호출하는 문장이 없어졌다.
출력 결과는 아래의 결과로 볼 수 있듯이 정상적으로 동작한다는 것을 알 수 있다.

6
2
8
2.0
10
-4
21
0.42857142857142855

상속

상속은 어떤 클래스를 만들 때 다른 클래스의 기능을 물려받을 수 있도록 만드는 것이다. 보통 기존 클래스를 변경하지 않고 기능을 추가하거나 기존 기능을 변경하려고 할 때 사용한다.

  • 기본구조
class 클래스_이름(상속할_클래스_이름)
  • 상속클래스 추가
class morecal(calculator):
    pass

a = morecal(4, 2)
b = morecal(3, 7)

print(a.add())
print(a.sub())
print(a.mul())
print(a.div())

print(b.add())
print(b.sub())
print(b.mul())
print(b.div())

morecal클래스를 새로 생성하고 calculator 클래스를 상속하게 했다.
아래의 출력 결과를 통해 객체 타입을 morecal로 변경하고 수행해도 결과는 상속받은 그대로 연산되는 것을 알 수 있다.

6
2
8
2.0
10
-4
21
0.42857142857142855

  • 상속을 통해 제곱연산 추가
class morecal(calculator):
    def pow(self):
        result = self.first ** self.second
        return result

a = morecal(4, 2)
b = morecal(3, 7)

print(a.pow())
print(b.pow())

a의 b제곱을 계산하는 morecal클래스에 pow()메서드를 추가한 후 결과를 확인해보았다.

16
2187

상속은 위의 예제처럼 기존 클래스는 그대로 둔 채 클래스의 기능을 확장시킬 때 주로 사용하기도 한다.

  • 메서드 오버라이딩(Overriding; 덮어쓰기

calculator 클래스의 div함수를 실행시킬 때 다음과 같은 오류가 나타날 수 있다.

class calculator:
    def __init__(self, first, second):
        self.first = first
        self.second = second
        
    def setdata(self, first, second):
        self.first = first
        self.second = second
        
    def div(self):
        result = self.first / self.second
        return result
        
a = calculator(4, 0)
    
print(a.div())

Traceback (most recent call last):

File "/Users/sangwoo/.spyder-py3/temp.py", line 37, in module
print(a.div())

File "/Users/sangwoo/.spyder-py3/temp.py", line 23, in div
result = self.first / self.second

ZeroDivisionError: division by zero

이 오류는 4를 0으로 나누려고 하기 때문에 ZeroDivisionError오류가 발생한다.
이런 경우 부모 클래스인 calculator에 있는 div 메서드를 동일한 이름으로 다시 만드는데 이것을 메서드 오버라이딩이라고 한다.

class divmore(calculator):
    def div(self):
        if self.second == 0:
            return 0
        else:
            return self.first / self.second
        
a = divmore(4, 0)

print(a.div())

위의 코드는 ZeroDivisionError오류 없이 수행할 수 있게 작성한 상속 클래스이다.

0

결과에서 볼 수 있듯이 메서드를 오버라이딩하면 부모 클래스의 메서드 대신 오버라이딩한 메서드가 호출된다.

클래스 변수

클래스 변수는 클래스 안에 함수를 선언하는 것과 마찬가지로 클래스 안에 변수를 선언하여 사용한다.

class family:
    lastname = "Kim"
    
print(family.lastname)

위의 코드에서 볼 수 있는 것처럼 클래스 변수는 (클래스_이름.클래스_변수) 로 사용할 수 있다.

Kim

class family:
    lastname = "Kim"

a = family()
b = family()

print(a.lastname)
print(b.lastname)

또는 이렇게 family 클래스로 만든 객체를 통해서도 클래스 변수를 사용할 수 있다.

Kim
Kim

클래스에 정의된 lastname을 "Park"으로 변경하면 결과가 Park으로 출력되는 것을 알 수 있다.

>>> id(family.lastname)
140316071103856
>>> id(a.lastname)
140316071103856
>>> id(a.lastname)
140316071103856

위의 결과 처럼 id() 를 콘솔에서 사용해보면 클래스 변수가 공유된다는 사실을 알 수 있다.

profile
아침엔 운동하고 밤엔 잠을 잔다.

0개의 댓글