[플레이데이터] 4월 24일 오전 수업 -1(파이썬 클래스)

싱숭생숭어·2023년 4월 24일
0

플레이데이터 수업

목록 보기
4/21

클래스와 객체

클래스를 가장 잘 설명해주는 그림

  • 과자 틀 -> 클래스
  • 과자 틀로 만든 과자 -> 객체

클래스(class)란 똑같은 무엇인가를 계속해서 만들어 낼 수 있는 설계 도면(과자 틀)이고, 객체(object)란 클래스로 만든 피조물(과자 틀로 만든 과자)를 뜻함.

여기서 클래스로 만든 각 객체마다 고유한 성격을 가진다. 과자 틀로 만든 과자에 손상을 가해도 다른 과자에는 아무 영향이 없는 것과 마찬가지 !

껍질뿐인 클래스 만들기

class Cookie:
	pass

클래스로 객체 만들기

a = Cookie()
b = Cookie()

위와 같이 1개의 클래스로 무수히 많은 객체를 만들어 낼 수 있다. Cookie()의 결괏값을 돌려받은 a와 b가 바로 객체이다.

객체와 인스턴스의 차이
클래스로 만든 객체를 인스턴스라 한다. a = Cookie()이렇게 만든 a는 객체이자, Cookie의 인스턴스이다. 즉 인스턴스라는 말은 특정 객체(a)가 어떤 클래스(Cookie)의 객체인지를 관계 위주로 설명할 때 사용한다.

isinstance를 이용하여 해당 클래스의 인스턴스인지 확인

isinstance(a, Cookie)
>>> True

dir을 사용하여 인스턴스가 가진 속성 확인

dir(a)
>>> ['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'content',
 'num',
 'output']

클래스의 메서드 만들기

FourCal()이라는 클래스를 사칙연산이 가능하도록 기능을 추가해야한다.

class FourCal:
	pass

라는 껍질뿐인 class에 숫자를 지정할 수 있는 기능을 추가할 것이다.

class FourCal:
	def setdata(self, first, second):  #메서드의 매개변수
    seld.first = first 					#메서드의 수행문
    self.second = second				#메서드의 수행문

클래스 안에 구현된 setdata함수는 다른 말로 메서드(method)라고 부른다. 메서드는 클래스에 포함되어 있다는 점 외에는 일반 함수와 다른 점이 없다.

메서드의 매개변수

setdata의 메서드는 매개변수로 self, first, second 3개의 입력값을 받는다. 이 중 일반 함수와는 달리 메서드의 첫번째 매개변수 self는 특별한 의미를 갖는다.

setdata 메서드에는 self, first, second 총 세개의 매개변수가 필요한데, 실제로는 a.setdata(4,2)처럼 2개 값만 전달한다. 이유는 setdata의 첫번째 매개변수 self -> setdata 메서드를 호출한 객체 a가 자동으로 전달됨 ! (파이썬 메서드의 첫번째 매개변수 이름으로 관례적으로 self를 사용함. 객체 호출 시 호출한 객체 자신이 전달되기 때문 !)

메서드의 또 다른 호출 방법

a = FourCal()
a.setdata(4,2)

객체(a) + 메서드(setdata) 형태로 호출 시 self 생략해서 호출

a = FourCal()
FourCal.setdata(a,4,2)

클래스이름(FourCal) + 메서드(setdata) 형태로 호출 시 객체 a를 첫번째 매개변수 self에 꼭 전달 필요

 class FourCal:
 	def setdata(self, first, second):
    	self.first = first
        self.second = second
    def add(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

-> 더하기, 곱하기, 빼기, 나누기 등을 가능하게 메서드를 추가한 class

인스턴스 메서드

  • 인스턴스 메서드를 정의하는 구문은 함수 정의와 같음
  • 클래스 정의 시 첫 번째 인수에 self를 지정하는 것 외에는 일반적인 함수와 동일

생성자(Constructor)

a = FourCal()
a.add()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in add
AttributeError: 'FourCal' object has no attribute 'first'

FourCal 클래스의 인스턴스 a에 setdata 메서드를 수행하지 않고 add 메서드를 먼저 수행하면, AttributeError: 'FourCal' object has no attribute 'first' 오류가 발생한다. 이는 setdata 메서드를 수행해야 객체 a의 객체변수 first와 second가 생성되기 때문

-> 이렇게 객체에 first, second와 같은 초깃값을 설정해야 할 필요가 있을때는 setdata와 같은 메서드를 호출해 초깃값을 설정하는 것 보다 생성자를 구현하는 것이 안전함 !
(생성자란 객체가 생성될 때 자동으로 호출되는 메서드)

def __init__(self, first, second):
    self.first = first
    self.second = second

메서드 이름을 setdata에서 __init__로만 바꿔도 자동으로 생성자로 인식된다.
따라서 생성자를 활용한 class의 경우, 객체를 생성할때부터 first와 second에 해당되는 값을 전달하여야 한다.
a = FourCal() -> a = FourCal(4,2)

클래스의 상속

  • 상속(inheritance)란 어떤 클래스를 만들 때 다른 클래스의 기능을 물려받을 수 있게 만드는 것 ! (예제로는 위에서 만든 FourCal 클래스에 a^b을 구할 수 있는 기능을 추가)

기존 클래스에 기능을 수정하는 대신 왜 굳이 상속을 쓰냐 !
-> 기존 클래스가 라이브러리 형태로 제공되거나 수정이 허용되지 않는 상황이라면 상속을 활용해야 함
상속의 경우, 기존 클래스(FourCal)은 그대로 놔둔 채 클래스의 기능을 확장시킬 때 사용

class MoreFourCal(FourCal):
	def pow(self):
    result = self.first ** self.second 
    return result
  • 클래스를 상속하기 위해서는 다음처럼 클래스 이름 뒤 괄호 안에 상속할 클래스 이름을 넣어줌

메서드 오버라이딩

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

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    result = self.first / self.second
ZeroDivisionError: division by zero

FourCal 클래스의 객체 a에 4와 0 값을 설정하고 div 메서드를 호출하면 분모가 0이기에 위와 같은 ZeroDivivionError 오류가 발생함. 하지만 0으로 나눌때 오류가 아닌 0을 리턴하고자 한다면 ?

-> FourCal 클래스를 상속하는 SafeFourCal 클래스를 생성

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

이런 식으로 부모 클래스(상속한 클래스)에 있는 메서드를 동일한 이름으로 다시 만드는 것을 메서드 오버라이딩(덮어쓰기)이라고 한다. 이렇게 메서드를 오버라이딩하면 SafeFoulCal(4,0) 수행 시 부모클래스의 메서드 대신 오버라이딩한 메서드가 호출된다 !

클래스 변수

  • 클래스 변수란 클래스 내, 함수 밖에서 변수명 = 데이터 형식으로 정의한 변수로서 클래스에서 생성한 모든 객체가 공통으로 사용

  • 아래와 같이 클래스명.변수명로 사용하거나, 객체를 생성한 후 객체(a).변수명 통해서도 클래스 변수를 접근 가능

class Family:
	lastname = "김"
Family.lastname

>>>
a = Family()
a.lastname

>>>
  • Family.lastname = "박"으로 변수를 바꾸면 클래스로 만든 모든 객체의 lastname 변수가 모두 변경된다. (모든 객체에 공유됨)

인스턴스 변수

  • 인스턴스 변수란 클래스 내의 함수 안에서 self.변수명 = 데이터 형식으로 정의한 변수로 클래스 내의 모든 함수에서 self.변수명 으로 접근 가능
  • 인스턴스 변수는 각 인스턴스가 독립적으로 가짐
  • 아래 예시는 title에 새로운 인스턴스 변수인 selction을 정의하려 함
  • 그러나 다른 인스턴스 first_page에 그 속성은 존재하지 않으므로 접근 시 AttributeError가 발생

a.lastname = "최"(a 객체의 변수만 변경됨 -> 이게 인스턴스 변수)
a.lastname
>>>"최"
Family.lastname
>>>"박"
b.lastname
>>>"박"

  • 클래스 변수와 같은 이름의 인스턴스 변수를 정의하면 그 인스턴스의 속성을 사용해 클래스 변수에 접근할 수 없음 -> 이는 클래스 객체의 속성보다 먼저 인스턴스 객체의 속성이 검색되기 때문 !

profile
공부합시당

0개의 댓글