와이드윤 2020. 12. 15. 17:18
728x90

"""

파이썬 공부 14일차

20200804

"""

 

슬슬 업로드되는 시간이 늦어진다.

왜냐면 집에서 뒹굴거리다 느즈막히 시작하기 때문.. 진작 집에서 할걸 내 아까운 커피값

 

생성자(Constructor)

어제 나왔던 FourCal 클래스의 인스턴스 a에 setdata 메서드를 수행하지 않고 add 메서드를 수행하면

'AttributeError: 'FourCal' object has no attribute 'first''라는 오류가 발생하는데,

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

 

객체에 초기값을 설정해야 할 경우 setdata와 같은 메서드를 호출해서 설정하기 보다는 생성자를 구현하는 것이 더욱 안전한 방법이다.

생성자는 객체가 생성될 때 자동으로 호출되는 메서드고, __init__ (양 옆으로 _ 2개)을 사용하면 생성자가 된다.

class FourCal:
	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

__init__ 메서드는 생성자로 인식되어 객체가 생성되는 시점에 자동으로 호출된다.

 

# 클래스의 상속

클래스의 상속은 어떤 클래스를 만들 때 다른 클래스의 기능을 물려받을 수 있게 만드는 것인데,

FourCal 클래스에 a^b를 구할 수 있는 기능을 추가해보자. (MoreFourCal)

class MoreFourCal(FourCal):
	pass

클래스를 상속하기 위해서는 클래스 이름 뒤 괄호 안에 상속 할 클래스 이름을 넣어주면 된다.

class 클래스 이름(상속할 클래스 이름):

MoreFourCal 클래스는 FourCal 클래스를 상속했기 때문에 FourCal 클래스의 기능을 모두 사용할 수 있어야 한다.

a = MoreFourCal(4, 2)
print(a.add(), a.mul(), a.div(), a.sub())
>>> 6 8 2.0 2

성공

그렇다면 왜 상속을 사용할까?

상속은 기존의 클래스를 변경하지 않고 기능을 추가하거나 기존의 기능을 변경하려고 할 때 사용한다.

그렇다면 기존의 클래스를 직접 수정하면 되는데 왜 굳이 상속을 받아서 처리해야하지? 라는 생각이 든다.

하지만, 기존의 클래스가 라이브러리 형태로 제공되거나 수정이 허용되지 않는 상황일 때 상속을 사용해야 한다.

이제 a^b 기능을 추가해보자.

class MoreFourCal(FourCal):
	def pow(self):
		result = self.first ** self.second
		
        return result

a = MoreFourCal(4, 2)
print(a.pow())
>>> 16

 

# 메서드 오버라이딩

FourCal 클래스의 객체 a에 4와 0을 설정하고, div 메서드를 호출하면 4를 0으로 나누려하기 때문에 'ZeroDivisionError'가 발생한다.

그렇다면, 0으로 나눌 때 오류가 아닌 0을 돌려주도록 만들고 싶을 땐 어떻게 해야할까?

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

FourCal 클래스를 상속하는 SafeFourCal 클래스를 만들었다.

SafefourCal 클래스는 FourCal 안에 있는 div 메서드를 동일한 이름으로 다시 작성했다.

부모 클래스(상속한 클래스)에 있는 메서드를 동일한 이름으로 다시 만드는 것을 메서드 오버라이딩이라고 하는데,

이 경우 부모클래스의 메서드 대신 오버라이딩한 메서드가 호출된다.

a = SafeFourCal(4, 0)

print(a.div())
>>> 0

 

# 클래스 변수

객체변수는 다른 객체들에 영향을 받지 않고 독립적으로 그 값을 유지한다.

객체변수와는 성격이 다른 클래스 변수에 대해 알아봅시다.

class Family:
	lastname = '김'

Family 클래스에 선언한 lastname이 클래스 변수다.

클래스 변수는 클래스 안에 함수를 선언하는 것처럼 클래스 안에 변수를 선언하여 생성하는 것이다.

클래스 이름.클래스 변수로 사용하거나 Family 클래스로 만든 객체를 통해 사용할 수도 있다.

print(Family.lastname)
>>> 김
a = Family()
b = Family()

print(a.lastname)
print(b.lastname)
>>> 김
>>> 김

 

클래스 변수는 클래스로 만든 모든 객체에 공유된다.

print(id(Family.lastname))
print(id(a.lastname))
print(id(b.lastname))
	# 셋 모두 같은 id 값을 가짐

어제 책에 없는 문제를 풀어봤는데, 역시 나는 우물안의 개구리였다.

더 열심히 해야겠단 생각이 든 순간이여따.

 

 

728x90