오름캠프 - Python 처음 배우는 파이썬 클래스

프로필 사진mingke

오름캠프 Python Class

목차

파이썬 클래스

최근 오름캠프에서 Python class 진도를 나갔습니다. 많은 분들이 class를 어려워하셨습니다. Python은 객체지향프로그래밍 언어로 class를 잘 아는 것은 기본입니다. 객체를 만드는 틀이 class이기 때문입니다. 서브강사로서 자습시간에 훈련생 분들과 class 복습을 했습니다. 관련 내용을 블로그에 포스팅하려고 합니다.

클래스 구성 요소 및 작성 방법

Python의 클래스를 구성하는 요소들은 다음과 같습니다.

  • class 키워드 - 클래스를 정의하기 위해 필요한 키워드 입니다.
  • 클래스 이름 - 클래스가 가지는 이름입니다. class 키워드 다음에 입력합니다.
  • 부모 클래스 이름 - 클래스가 상속을 받는 다면 상속하는 부모 클래스의 이름을 넣어주어야 합니다.
  • 클래스 속성 - 클래스가 기본적으로 가지는 속성입니다.
  • 생성자 - 클래스를 인스턴스로 만들 때 인스턴스 속성을 생성하는 기능을 합니다.
  • 인스턴스 속성 - 클래스를 인스턴스로 만들었을 때 가질 수 있는 속성입니다.
  • 메소드 - 클래스에 구현된 기능을 나타냅니다. def 키워드를 사용하여 함수 형태로 작성합니다.

크게 보면 기본적으로 알아야 할 구성요소는 이정도가 될 것 같습니다.

코드로 한 번 살펴보겠습니다.

# Phone(전화)라는 클래스를 만들어보겠습니다.
# class 클래스이름(부모 클래스 이름):
class Phone(object):
    # 들여쓰기(indentation) 4칸
    # 클래스 속성 - 클래스 바로 아래에 들여쓰기 후 변수처럼 작성
    # camera가 2개 있습니다. Phone 클래스로 만드는 인스턴스는 모두 2개의 카메라를 가집니다.
    camera_count = 2
 
    # 생성자 - 아래와 같이 선언하여 인스턴스 속성을 생성합니다.
    # 생성자도 일종의 메소드이며 메소드는 기본적으로 self 파라미터를 가집니다.
    def __init__(self, model, phone_number):
        # 인스턴스 속성
        self.model = model
        self.phone_number = phone_number
 
    # 메소드 - Phone의 기능 call, 전화를 거는 기능
    def call(self, target):
        print(f"{target}에 전화를 겁니다")
 
# 인스턴스 만드는 방법
my_phone = Phone("IPhone", "010-1234-1234")
 
# 클래스 속성 접근 방법
print(Phone.camera_count) # 2 출력
# 클래스 속성은 인스턴스에서도 접근할 수 있습니다.
# 인스턴스를 해당 클래스로 만들었기 때문입니다.
print(my_phone.camera_count) # 2 출력
 
# 메소드 실행
my_phone.call("010-1111-1111") # 010-1111-1111에 전화를 겁니다 출력
  • 파이썬 클래스는 기본적으로 object 라는 클래스를 상속받습니다. object객체
  • 객체를 상속받기 때문에 모든 클래스는 객체가 되는 것입니다.
  • 클래스 속성은 인스턴스에서 접근 가능하지만 인스턴스 속성과 메소드는 인스턴스에서만 접근이 가능합니다.
  • self 가 가리키는 것은 인스턴스 자기 자신입니다.
  • my_phone.call("010-1111-1111") 을 실행한다고 했을 때 python이 selfmy_phone 을 대신 넣어주는 것이라고 생각해도 됩니다.

클래스 추가 설명

클래스는 인스턴스 객체를 만드는 틀입니다. 객체는 우리 인간이 생각할 수 있는 물체, 개념 등 모든 것을 나타내며 소프트웨어 세상에서 파이썬으로 구현할 대상을 말합니다.

따라서 클래스를 생각할 때 다음과 같이 생각해보면 이해에 도움이 될 수도 있습니다.

  • 클래스를 영어의 명사형으로 생각합니다.
    • 어떤 물체, 개념 등 존재를 나타내는 것 이기에 명사형으로 생각할 수 있겠습니다.
    • Phone, Factory, Repository, Manager …
  • 클래스 속성 및 인스턴스 속성 또한 명사형으로 생각합니다.
    • 클래스 및 인스턴스의 속성 또한 명사처럼 생각할 수 있습니다.
    • 특정 클래스가 가지는 이름, 모델 등
    • Phone.name, Phone.model …
  • 메소드는 영어의 동사형으로 생각합니다.
    • 메소드는 클래스가 수행할 수 있는 행동이나 기능을 나타내기 때문에 동사형으로 생각할 수 있습니다.
    • 클래스의 기능 - 전화를 걸다, 메세지를 보내다.
    • Phone.call(), Phone.send_message() …

클래스 상속

클래스 상속은 말 뜻 그대로 자식 클래스가 부모 클래스에게 상속을 받아 부모 클래스의 속성과 메소드를 사용할 수 있게 되는 것입니다. 부모 클래스의 이미 정의된 것을 자식 클래스에서 재사용을 할 수 있게되니 코드의 재사용성이 증가합니다.

# 자식클래스 Tablet이 부모클래스 Phone을 상속 받습니다.
class Tablet(Phone):
    def __init__(self, model, phone_number, size):
        # super() -> 부모클래스를 가리킵니다. 부모클래스의 생성자를 가져와서 인스턴스 속성을 생성합니다.
        super().__init__(model, phone_number)
        self.size = size
 
 
# Tablet은 Phone을 상속받았기 때문에 camera_count에 접근 가능
print(Tablet.camera_count) # 2 출력
 
# 인스턴스를 만듭니다
my_tablet = Tablet("IPad", "010-1234-1234", 13)
# Phone에 있는 call메소드를 사용할 수 있습니다
my_tablet.call("010-1111-1111") # 010-1111-1111에 전화를 겁니다 출력

상속의 개념 자체는 어렵지 않습니다. 이미 정의된 클래스를 가져와서 확장시킨다는 느낌입니다. Phone을 확장시켜 Tablet을 만든 것처럼 말이죠.

DRF 코드에서 사용하는 상속 예시

django-restframework에서 사용한 간단한 예제를 살펴보겠습니다. 그리고 메소드 오버라이딩도 알아보도록 하겠습니다. django-restframework 는 django에서 api를 만드는데 사용하는 프레임워크입니다.

from rest_framework import serializers
from apis.models import Apply
 
class ApplySerializer(serializers.ModelSerializer):
    class Meta:
        model = Apply
        fields = ("id", "user", "job_post")
 
    # 메소스 오버라이딩
    # 아래 설명 참고
    def validate(self, attrs):
        user = attrs.get("user")
        job_post = attrs.get("job_post")
        queryset = Apply.objects.filter(user=user, job_post=job_post)
        if queryset.exists():
            raise serializers.ValidationError("동일한 회사에는 한 번만 지원할 수 있음")
        return attrs
  • 자식 클래스 ApplySerializerModelSerializer 라는 부모 클래스부터 상속을 받았습니다.
  • validate 라는 메소드를 재정의 하였는데, 이것을 메소드 오버라이딩 이라고 합니다.
    • attrs 를 파라미터로 받아 검증하는 메소드입니다. 그냥 이렇게 사용할 수 있구나 참고만 하면 될 것 같습니다.
    • 원래 부모 클래스의 validate 는 다음과 같습니다.
      # 부모 클래스의 validate를 그냥 사용하지 않고
      # 재정의하여 어떠한 검증 로직을 추가했습니다.
      def validate(self, attrs):
          return attrs
  • ApplySerializerModelSerializer 의 모든 것을 사용할 수 있습니다. ModelSerializer 가 가지고 있는 것들은 아래 링크에서 확인할 수 있습니다.
Loading...

마무리

클래스에 대해서 구구절절 떠들어 봤습니다. 최대한 쥐어 짜내서 쉬운 방법으로 자세하게 설명하려고 노력했습니다만, 사실 처음 배우는 입장에서 클래스가 바로바로 잘 이해되지는 않을 것 같습니다. 과거를 회상해보니 저 또한 그랬던 것 같습니다. 빨리 이해되고 익숙해 질 수 있도록 반복, 숙달하는 게 최고인 것 같습니다.