지구정복

[Python] 3/9 | 상속과 예외처리 본문

데이터 엔지니어링 정복/Python

[Python] 3/9 | 상속과 예외처리

eeaarrtthh 2021. 3. 9. 12:16
728x90
반응형

1. 상속

더보기

상속 예제
자식클래스에서 생성자를 정의하면 생성자 오버라이딩된다.

class Base:
    def __init__(self):
        print( 'Base 생성자' )
        
    def base_method(self):
        print( 'base method' )
    
class Derived(Base):
    def __init__(self):
        print( 'Derived 생성자' )

# base = Base()
# base.base_method()

#상속
derived = Derived()
derived.base_method()

 

자식클래스에서 부모클래스 메서드 호출하기

class Animal:
    def __init__(self):
        print( 'Animal __init__()' )

class Tiger(Animal):
    def __init__(self):
        Animal.__init__(self)
        print( 'Tiger __init__()' )
        
class Lion(Animal):
    def __init__(self):
        Animal.__init__(self)
        print( 'Lion __init__()' )
        
#다중 상속 허용 
class Liger(Tiger, Lion):
    def __init__(self):
        Tiger.__init__(self)
        Lion.__init__(self)
        print( 'Liger __init__()' )
        
liger = Liger()



이때 Animal 부모 생성자가 중복호출된다. 이를 방지하기 위해 super()를 사용한다.

class Animal:
    def __init__(self):
        print( 'Animal __init__()' )

class Tiger(Animal):
    def __init__(self):
        super().__init__()
        print( 'Tiger __init__()' )
        
class Lion(Animal):
    def __init__(self):
        super().__init__()
        print( 'Lion __init__()' )
        
#다중 상속 허용 
class Liger(Tiger, Lion):
    def __init__(self):
        super().__init__()
        print( 'Liger __init__()' )
        
liger = Liger()

#상속받고 있는 부모 클래스 확인하기
print( Liger.__bases__ )

#상속계통도 확인하기
print( Liger.__mro__ )

 

메소드 재정의하기

class Person:
    def __init__(self, name, phoneNumber):
        self.Name = name
        self.PhoneNumber = phoneNumber
    
    def PrintInfo(self):
        print( 'Info(name:{0}, Phone Number:{1}'.format(self.name, self.PhoneNumber) )

class Student(Person):
    def __init__(self, name, phonename, subject, studentid):
        self.name = name
        self.phonename = phonename
        self.subject = subject
        self.studentid = studentid
    
    def PrintInfo(self):
        print( 'Info(name:{0}, Phone Number:{1}'.format(self.name, self.phonename) )
        print( 'Info(Subject:{0}, Student ID:{1}'.format(self.subject, self.studentid) )
        
p = Person( 'Derick', '010-1111-1111' )
s = Student( 'Marry', '010-2222-2222', 'Computer Science', '123456' )

s.PrintInfo()

 

다중 상속

class Tiger():
    def __init__(self):
        print( 'Tiger __init__()' )
        
    def jump(self):
        print( '호랑이 점프' )
        
class Lion():
    def __init__(self):
        print( 'Lion __init__()' )
        
    def bite(self):
        print( '사자 물기' )
    
#다중 상속
class Liger(Tiger, Lion):
    def __init__(self):
        Tiger.__init__(self)
        Lion.__init__(self)
        print( 'Liger __init__()' )
    
    def play(self):
        print( '라이거 놀기' )

liger = Liger()
liger.jump()
liger.bite()
liger.play()

 

만일 똑같은 이름의 메소드가 부모클래스에 있을 경우를 확인해보자.
Tiger의 cry메서드를 불러오는 것을 확인할 수 있다. 이는 Liger클래스 선언부에 상속받는 순서가 Tiger클래스부터 시작됐기 때문에 우선적으로 Tiger클래스의 이름공간에서 cry 메서드를 찾기때문이다.
상속받는 순서를 Lion, Tiger로 바꾸면 Lion의 cry메서드가 불러진다.

class Tiger():
    def __init__(self):
        print( 'Tiger __init__()' )
        
    def jump(self):
        print( '호랑이 점프' )
        
    def cry(self):
        print( '호랑이 cry' )
        
class Lion():
    def __init__(self):
        print( 'Lion __init__()' )
        
    def bite(self):
        print( '사자 물기' )
    
    def cry(self):
        print( '사자 cry' )
    
#다중 상속
class Liger(Tiger, Lion):
    def __init__(self):
        Tiger.__init__(self)
        Lion.__init__(self)
        print( 'Liger __init__()' )
    
    def play(self):
        print( '라이거 놀기' )

liger = Liger()
liger.jump()
liger.bite()
liger.play()

#Liger바로 위에 Tiger가 있으므로 Tiger의 cry를 부른다.
print( Liger.__mro__ )
liger.cry()

 

 


2. 예외처리

더보기

아래와 같은 코드를 실행하면 error가 발생한다.
이러한 에러를 런타임오류라고 한다.
런타임에러는 실행시 값의 오류에 의해 발생하는 에러를 뜻한다.

num1 = 10
num2 = 0
print( num1 / num2 )
arr = [1, 2, 3]
print( arr[4] )

 

이러한 에러를 try구문으로 처리할 수 있다.

def divide( a, b ):
    return a / b

try:
    #c = divide( 20, 10 )
    #c = divide( 20, 0 )
    #ZeroDivisionError: division by zero
    
    c = divide( 20, 'string' )
    #TypeError: unsupported operand type(s) for /: 'int' and 'str'
    print( c )
except ZeroDivisionError:
    print( '0으로 나눌 수 없습니다.' )
except TypeError as e:  #에러를 e라는 변수에 저장
    print( '자료형태 오류', e.args[0] )   #e변수에 있는 에러 내용을 출력
except :
    print( '기타 에러' ) 
else : 
    print( '정상처리' )

 

raise구문

raise구문은 강제로 예외를 발생시킨다.

사용자 정의 예외

#사용자 정의 예외 정의
class NegativeDivisionError(Exception):
    def __init__(self, value):
        self.value = value
        
def PositiveDivide( a, b ):
    if( b < 0 ):
        raise NegativeDivisionError(b)
    return a/ b

try:
    ret = PositiveDivide( 10, -3 )
    print( '10 / 3 = {0}'.format(ret) )
except NegativeDivisionError as e:
    print( 'Error - Second argument of PositiveDivide is ', e.value )
except ZeroDivisionError as e:
    print( 'Error - ', e.args[0] )
except :
    print( "Unexpected exception!" )

 

 

 

 

 

 

 

728x90
반응형
Comments