Python

클래스

해파리냉채무침 2024. 3. 31. 16:42

출처: Do it! 점프 투 파이썬

class Calculator :
    def __init__(self) :
        self.result = 0

    def add(self, num) :
        self.result += num
        return self.result

cal1 = Calculator()
cal2 = Calculator()

calculator 클래스로 만든 별개의 계산기 cal1 cal2(객체)가 각 역할을 수행한다. 

클래스로 만든 객체를 인스턴스라고 한다. 여기서 cal1, cal2는 객체, cal1, cal2의 객체는 Calculator의 인스턴스이다. 

인스턴스는 특정 객체(cal1,cal2)가 어떤 클래스(Calculator)의 객체인지 관계 위주로 설명할 때 사용한다. 

cal1,cal2는 Calculator의 인스턴스, cal1,cal2는 객체 라고 한다. 

 

class FourCal :
    pass

a = FourCal()
print(type(a)) # <class '__main__.FourCal'>

여기서도 객체 a의 타입은 FourCal클래스이다.

 

class FourCal :
    def setdata(self, first, second) :
        self.first = first
        self.second = second

a = FourCal()
a.setdata(4, 2)
print(a.first) # 4
print(a.second) # 2

Fourcal 클래스 안에 구현된 setdata함수를 메서드(Method)라고 한다.

setdata 메서드의 첫번째 매개변수 self에는 setdata 메서드를 호출한 객체 a가 자동으로 전달된다. 

즉 a.setdata(4,2)일때, self는 a, first는 4, second은 2를 받는다. 

a= Fourcal()
Fourcal(a,4,2)

다음과 같이 클래스를 통해 메서드를 호출할 수 있다. 클래스.메서드 형태로 불러올 때는 맨 앞에 self인 a를 반드시 불러와야 한다.

 

class로 사칙연산 만들기

class FourCal :
    def setdata(self, first, second) :
        self.first = first
        self.second = second

    def sum(self) :
        result = self.first + self.second
        return result

    def mul(self) :
        result = self.first * self.second
        return result

    def sub(self) :
        result = self.first - self.second
        return result

    def div(self) :
        result = self.first / self.second
        return result
 
a = FourCal()
b = FourCal()
a.setdata(4, 2)
b.setdata(3, 7)
print(a.sum()) # 6
print(a.mul()) # 8
print(a.sub()) # 2
print(a.div()) # 2
print(b.sum()) # 10
print(b.mul()) # 21
print(b.sub()) # -4
print(b.div()) # 0

 

생성자(Constructor)

class FourCal :
    def setdata(self, first, second) :
        self.first = first
        self.second = second

    def add(self) :
        result = self.first + self.second
        return result
a = FourCal()
a.add()

다음과 같이 실행하면  AttributeError: 'Fourcal' object has no attribute 'first' 와 같은 에러가 난다. 

setdata 메서드를 수행해야 객체 a의 변수 first와 second가 생성되기 때문이다.

class FourCal:
    def __init__(self, first, second):
        self.first = first
        self.second = second
    def setdata(self, first, second):
        self.first = first
        self.second = second

다음과 같이 __init__ 을 추가하여 객체에 초기값을 설정한다. 생성자란 객체가 생성될 때 자동으로 호출되는 메서드를 의미한다. init 메서드도 생성자 이기 때문에 객체 생성 시점에 자동으로 호출된다. 

a= Fourcal()

실행하면 TypeError:__init__() missing 2 required positional arguments: 'first' and 'second' 과 같은 에러가 난다.

fourcal()을 수행할때 생성자 init의 매개변수 first와 second에 해당하는 값이 전달되지 않았기 때문이다. 

a = FourCal(4,2)

 

위와 같이 수행하면 매개변수에는 self에는 생성되는 객체 a, first에는 4, second에는 2가 들어간다. 

 

클래스의 상속

class MoreFourCal(FourCal):
    def pow(self):
        result = self.first ** self.second
        return result
        
a = MoreFourCal(4, 2)
# print(a.add()) 6
# print(a.pow()) 16

class 클래스 이름(상속할 클래스 이름) 으로 클래스를 상속한다. 위와 같이 상속하면 FourCal 클래스의 모든 기능을 사용할 수 있다. 

 

메서드 오버라이딩

a= FourCal(4,0)
a.div()

다음과 같이 실행하면 ZeroDivisionError 오류가 발생한다.

0으로 나눌때 오류가 아닌 0을 돌려주도록 하고싶으면 다음과 같이 코드를 수정한다.

class SafeFourCal(FourCal):
    def div(self): 
        if self.second == 0:
            return 0
        else:
            return self.first / self.second

a = SafeFourCal(4, 0)
# print(a.div())

FourCal을 상속하여 받아와서 FourCal 클래스에 있는 div 메서드를 동일한 이름으로 다시 만든다.

이러한 과정을 메서드 오버라이딩이라고 한다. 이렇게 하면 부모 클래스(FourCal) 클래스 메서드 대신 오버라이딩한 메서드가 호출된다. 

 

class Family:
    lastName = '김'

print(Family.lastName) #김
a= Family
b= Family
print(a.lastname) #김
print(b.lastname) #김
Family.lastName = '박'
print(a.lastName)#박
print(b.lastName)#박

Family 클래스의 변수값을 변경했더니 클래스로 만든 객체의 lastname 값도 모두 변경된다. 

 

if__name__ : "__main__":의 의미

#mod1.py
def add(a,b):
   return a+b
def sub(a+b):
   return a-b

print(add(1,4))
print(sub(4,2))

위의 mod1.py 파일을 수행했을 때, 

C\:User>python mod1.py

5

2

다음과 같이 출력 된다. 

C\:User>python 
>>> import mod1
5
2

add와 sub 함수 사용을 위해 mod1을 import 했지만, mod1.py가 실행이 되어 결과를 출력한다. 다음과 같은 문제를 방지하기 위해 코드를 수정한다.

#mod1.py
def add(a,b):
   return a+b
def sub(a+b):
   return a-b
if __name__ == "__main__":
   print(add(1,4))
   print(sub(4,2))

다음과 같이 수정하고 출력했을 때, import mod1 다음 아무 결과값도 출력되지 않은 것을 알 수 있다.

 

오류 회피하기

try:
  f= open('없는파일','r')
except FileNotFoundError:
  pass

try문 안에서 FileNotFoundError가 발생할 경우에 pass를 사용하여 오류를 그냥 회피하도록 한다.

 

오류 일부러 발생시키기

class Bird:
    def fly(self):
        raise NotImplementedError

 

 

raise 명령어를 통해 오류를 강제로 발생시킬 수 있다.

class Eagle(Bird):
    pass
eagle = Eagle()
eagle.fly()

만약 자식 클래스 Eagle이 Bird를 상속하고 Eagle 클래스를 호출했을때, raise 문에 의해 NotImplemented Error가 발생한다. 

class Eagle(Bird):
    def fly(self):
        print('very fast')

Eagle 클래스에 fly 함수를 구현해서 오류발생을 제거한다.