Class 쉽게 이해하기 - python

이찬·2023년 6월 10일
0

Python

목록 보기
7/17
post-thumbnail

클래스는 제품의 설계도
객체 : 설계도로 만든 제품
생성자 : 객체를 만들 때 가장 먼저 실행되는 함수

class 클래스 이름:
def 메서드 이름(self):
명령블록

self : 객체 자기 자신

객체 = 클래스 이름()
객체.메서드 : .은 "~~의"

속성 추가하기

class Monster:
   def __init__(self,name):
        self.name = name
 #이때 self.name이 monster class의 속성이 된다
   def say(self):
       print(f"나는 {self.name}")
shark = Monster("상어")
#name변수에 상어가 들어가고, self에는 shark가 들어간다.

=================================================

클래스(Class)란 무엇인가
클래스는 자료형을 위한 일종의 템플릿이라고 생각하면 된다. 클래스 안에는 다양한 유형의 정보가 담겨 있고, 우리가 자료형과 어떻게 상호작용할 것인지 적혀 있다.

class 정의하기

class TestClass:
pass

인스턴스

클래스를 정의하고 나면 그걸 불러와서 사용하는 법을 알아야겠지. 클래스를 이용해 인스턴스(instance)를 만들어주면 된다. “임시로 어떤 템플릿을 불러와서 그걸 다른 이름의 객체로 저장한다”

test_instance = TestClass()

=> 클래스 이름에 괄호를 추가하여 인스턴스를 만들고, 그걸 변수 test_instance에 할당하는 방식

  • 물론 수많은 인스턴스를 호출하는 것도 가능하다. 어차피 클래스는 템플릿이고, 이걸 각기 다른 용도로 사용할 수 있기 때문이다

객체 지향 프로그래밍 (Object-Oriented Programming)
클래스 인스턴스는 객체(object)라고도 하며, 이렇게 클래스를 정의하고 객체를 만드는 패턴을 객체 지향 프로그래밍(OOP)이라고 한다.

인스턴스를 불러온다는 건 클래스를 가져와 객체로 바꿔준다는 건데, type() 함수를 사용하는 건 그 반대라고 생각하면 된다. 객체의 type을 확인해보면 해당 객체가 어떤 클래스의 인스턴스인지를 확인할 수 있다.

클래스 변수

클래스를 정의할 때 그 안에서 변수를 정의하면 모든 인스턴스에서 동일한 데이터를 사용할 수 있다. 이를 클래스 변수라고 부르는데, 이렇게 정의된 클래스 변수는 object.variable 구문을 사용하여 접근 가능

class Musician:
title = "Rockstar"

drummer = Musician()
guitarist = Musician()
print(drummer.title)
print(guitarist .title)

메서드 (Methods)

  • 메서드는 클래스 안에서 정의된 함수

  • 일반적인 함수를 정의할 때와 차이 : 메서드를 정의할 때는 첫 번째 인수를 항상 self로 지정해야 함

class Musician:
    title = "Rockstar"
    def explanation(self):
        print("I am a {}!".format(self.title))
drummer = Musician()
drummer.explanation()
#I am a Rockstar!

단순히 클래스 변수 title을 사용해서 문자열을 출력하는 메서드를 정의해하고, 그걸 불러와서 사용했다.

메서드를 작성할 때 다른 인수는 필요 없었기 때문에 self만 써주었고, 함수 안에서 클래스 변수를 사용할 때는 self.title과 같은 형식으로 불러왔다.

class Circle():
    pi = 3.14
  
    def area(self, radius):
        return self.pi * radius ** 2
  
circle = Circle()
pizza_area = circle.area(6)
table_area = circle.area(18)

Circle이라는 클래스에서 π(pi) 값은 3.14로 넣어주고, 원의 넓이 구하는 공식을 area라는 메서드로 정의했다. 원의 넓이는 π * 반지름²이다. 그리고 메서드를 정의할 때 반지름을 인수로 받아야 하기 때문에 area의 인수로 self와 radius를 넣어줬다. (메서드의 첫 번째 인수는 언제나 self다.)

생성자 (Constructor)

클래스를 호출할 때 자동으로 어떤 함수를 실행하거나 값을 호출하고 싶다면 생성자(Constructor)라는 걸 정의하면 된다.

메서드 정의할 때와 똑같긴 한데 메서드 이름으로 init을 사용하면 된다.

class Shouter:
    def __init__(self):
        print("HELLO?!")
shout = Shouter()

Shouter라는 클래스를 객체로 불러올 때마다 “HELLO?!”라는 문자열이 즉시 출력된다.

물론 클래스를 호출할 때 애초에 다른 인수(매개변수)를 받는 방식으로 정의하는 것도 가능하다. 이렇게

class Circle:
    pi = 3.14
    def __init__(self, radius):
        print("New circle with radius: {}".format(radius))
table = Circle(18)

인스턴스 변수 (Instance Variables)

지금까지 객체가 클래스의 인스턴스라는 것을 배웠지만, 각 객체가 메서드와 클래스 변수만으로 이루어져 있다면 객체들을 구별해야 할 필요가 있을까?

객체를 구별해서 인스턴스를 생성하는 이유는 각 인스턴스가 다른 종류의 데이터, 즉 인스턴스 변수를 보유할 수 있기 때문이다.

이렇게 각 객체가 보유한 데이터인 인스턴스 변수는 해당 클래스의 모든 인스턴스가 공유하는 게 아니다. (이게 클래스 변수와의 가장 큰 차이점이다.)

예를 보자. 일단 빈 클래스를 하나 정의해놓고, 두 개의 인스턴스(객체)를 불러오자.

class FakeDict:
    pass
fake_dict1 = FakeDict()
fake_dict2 = FakeDict()

그리고 각 객체에 fake_key라는 인스턴스 변수로 각각 다른 값을 넣어주면,

fake_dict1.fake_key = "This works!"
fake_dict2.fake_key = "This too!"

이걸 별도로 사용할 수 있다.


working_string = "{} {}".format(fake_dict1.fake_key, fake_dict2.fake_key)
print(working_string)
# "This works! This too!"

어려운 게 아니다. 그냥 그동안 사용했던 변수의 개념이라고 생각하면 편하다.

인스턴스 변수의 활용, self

왜 굳이 인스턴스 변수를 사용할까? 그냥 변수로 써도 문제 없는데?

  • 설계도인 클래스에서 수많은 객체들이 만들어 지는데, 정작 methods는 클래스안에 하나만 존재합니다. 즉 객체들마다 데이타인 attribute는 위의 예제처럼 학생 하나 하나 마다 다르지만, 사실상 함수인 methods는 동일한 셈입니다. 학생별로 데이터는 다르지만 기능인 함수는 다를바가 없는 것이죠. 따라서 클래스의 함수는 "내가 지금 어떤 객체의 데이터를 다뤄야 하는 거지?"라는 의문에 답으로 객체에 대한 정보를 갖는 self 변수를 첫번째 입력 파라메타로 받아야 합니다.

인스턴스를 생성할 때 작동하는 생성자(constructor)를 활용해서 인스턴스 변수를 생성하고 관리하면 너무나 편리하기 때문이다.

class AutoEmail:
    def __init__(self, name):
        self.name = name
mail_to_park = AutoEmail("PARK")
mail_to_kim = AutoEmail("KIM")
print(mail_to_park.name)
# "PARK"
print(mail_to_kim.name)
# "KIM"

인스턴스를 만들 때 애초에 이름을 넣어주었기 때문에 각 인스턴스의 name에서 그 이름을 그대로 가지고 있게 된다.

그러면 이걸 활용해서 메서드를 작성할 수도 있다.

class AutoEmail:
    intro = "안녕하세요"
    def __init__(self, name):
        self.name = name
    def say_hello(self):
        return "{intro} {name} 님".format(intro=self.intro, name=self.name)
mail_to_park = AutoEmail("PARK")
mail_to_kim = AutoEmail("KIM")
print(mail_to_park.say_hello())
# "안녕하세요 PARK 님"
print(mail_to_kim.say_hello())
# "안녕하세요 KIM 님"

클래스 변수와 인스턴스 변수를 모두 자유롭게 사용할 수 있게 되는 거다.

이게 바로 객체 지향 프로그램 작성의 장점일 거다. 클래스를 작성하여 필요한 데이터를 구조화하고, 해당 데이터와 의미있는 방식으로 상호 작용하는 메서드를 작성하는 것. 구조를 잘 짜는 게 중요하다.

파이썬에서는 모든 게 다 객체(Object)다

print(dir([]))

dir()은 어떤 객체를 인자로 넣어주면 해당 객체가 어떤 메서드를 가지고 있는지 돌려준다.

우리가 파이썬에서 다루는 모든 자료형은 모두 int, float, str, list, dict와 같은 이름을 가진 클래스의 인스턴스인 셈이다.

profile
Kyunghee univ. IE 21

0개의 댓글