class

newhyork·2022년 6월 23일
0

object vs instance


  • 클래스를 통해 생성된 것을 가리킬 때는 ‘객체(object)’,
    객체와 클래스와의 관계에 대해 말할 때는 ‘인스턴스(instance)’
    라고 각각 구분해서 사용하곤 한다.
    • ‘a는 인스턴스’ 보단, ‘a는 객체’.
    • ‘a는 어떤 클래스의 객체’ 보단, ‘a는 어떤 클래스의 인스턴스’.
  • (참고로 사실 Python에서는 모든 것이 객체이다. 즉, 클래스에 의해 생성된다.)

type() vs isinstance()

  • type(): 어느 클래스를 통해 생성된 객체인지 까지만 확인한다.
  • isinstacne(): 어떤 객체의 클래스 상속 관계까지도 확인한다.

class variable


  • 클래스 내, 메서드 밖에서 정의한 변수이다.
  • object variable은 각 객체 간에 독립적인 반면, 이는 전역변수처럼 사용하는 것이다.
    즉, 모든 객체 간에 값이 공유된다.
  • ‘클래스명(혹은 객체).클래스변수명’ 으로 참조한다.

class function


  • 클래스 내에서 정의한, 메서드와는 다른, 함수이다.
    • ‘클래스 자체가 가진 함수’ 라는 정도의 의미를 가지고 있다.

usage

class ClassName:
    @classmethod
    def class_function(cls[, parameter]):
        return
- @classmethod 라는 클래스 데코레이터를 통해 정의한다.
  - 클래스 데코레이터나 함수 데코레이터나 그 기능은 비슷하다. 
- 메서드의 self가 객체 자신인 것처럼, 클래스 함수의 첫번째 매개변수는 클래스 객체이다.
  - 통상적으로 변수명은 cls로 둔다.


ClassName.class_function([parameter])

magic method


  • 메서드 명 앞 뒤로 언더바(’_’) 두 개가 있는 형태로, 던더 메서드 라고도 한다.
  • 생성자(constructor): 객체가 생성될 때 호출된다.
  • 소멸자(destructor): 객체가 사라질 때 호출된다.
    • 가비지 컬렉터(garbage collector): 더 이상 쓰일 가능성 없이
      쓸데없이 메모리를 차지하고 있는 데이터들을 메모리에서 제거한다.
      • 변수에 저장되지 않으면 사용하지 않는 것으로 간주하여 삭제 대상이 된다.
        어떤 함수에서 나와 지역변수를 활용할 수 없게 되는 경우도 마찬가지다.
      • 프로세스가 종료되게 되면 모두 메모리에서 내려가므로,
        적어도 그 때는 객체들에 대해 소멸자가 호출된다.
  • __str__, __eq__, __len__, __contain__ 등:
    기본 함수나 연산자 등을 클래스마다 각기 특수한 형태로 사용하고자 할 때 이용한다.
    • __str__: str(객체) 로, 객체를 문자열 형태로 return하고자 할 때 사용한다.
      print문에서 단순히 객체만 print할 때는, str()을 쓰지 않아도 문자열로 return된다.
      (참고로 기본 내장된 str()은 함수가 아니라 클래스이다.)
    • 기존의 함수나 연산자를 그대로 쓰는 것이기 때문에 사용에 혼란(에러)이 있을 수 있다.
      따라서, 같은 클래스로부터 생성된 객체에만 해당 함수나 연산자를 적용하기 위해
      매직 메서드 내에 isinstance()를 두어, 이를 통해 구분하는 방식으로 사용하곤 한다.

getter/setter


  • 객체 변수(속성 내지는 필드)를 self.__객체변수명 형태로 선언하면, 클래스 외부에서는 참조할 수 없다.
    이를 private variable이라 한다.
  • private variable을 간접적으로 참조/재할당할 수 있게 정의해둔 메서드를
    각각 getter/setter라 한다.
    • 굳이 private variable을 쓰면서 getter/setter를 두는 이유는,
      객체의 무결성을 보장하기 위함이다.
      즉, getter/setter 메서드의 내부 로직을 통해 private variable에 접근하도록 하여
      무분별한 값으로 재할당하는 것을 방지할 수 있다.
  • Python에서는 getter/setter 정의 및 사용의 편의를 위해 데코레이터를 제공한다.
    • getter에는 @property, setter에는 @변수명.setter 형태로 둔다.
      이를 이용하기 위해선 특별히 메서드명을 둘 다 private variable과 동일하게 해줘야 한다.
    • 클래스 외부에서도 참조할 수 있게 되어
      private variable을 private하지 않게 일반적인 객체 변수처럼 사용할 수 있다.
    • 메서드 형태가 아닌, 변수 형태로 getter/setter를 호출하여 사용할 수 있게 된다.

usage

class Square:

    def __init__(self, side):
    self.__side = side

    @property
    def side(self):
        return self.__side

    @side.setter
    def side(self, value):
        self.__side = value


square = Square(5)
print(square.side)  # 5  (getter)
square.side = 10         (setter)
print(square.side)  # 10

inheritance


super()

  • 조상 클래스의 인스턴스를 반환하는 클래스이다.
    • 기본적으로 인자 없이 사용하여 호출하면 부모 클래스를 불러오고,
      인자를 두어 조상 클래스를 불러올 수도 있다.
  • 특히 생성자 메서드와 관련하여 ‘확장’에 자주 쓰인다.
    자식 클래스에서 overriding을 하려고 할 때,
    조상 클래스와 공통으로 사용되는 부분은 재작성할 필요 없게 해준다.

overriding

  • 자식 클래스에서 상속을 하고서,
    부모 클래스에서 정의한 변수나 메서드를 덮어써서 새로 정의하는 것이다.
  • 확장을 위해서는 super()와 함께 주로 사용된다.

abstract class

  • 해당 클래스는 추상 클래스로, 따로 직접적인 인스턴스를 갖지 않도록 한다.
    자식 클래스에 의해 상속되어 사용될 목적이다.
    (사실 내부적으로는, 자식 클래스의 인스턴스가 생성될 때
    부모 클래스의 인스턴스도 동시에 생성된다고 한다.)
    • super()를 통해, 조상 클래스로써 생성자 메서드를 제공하는 등의 형태로 주로 이용된다.
    • 추상 메서드를 정의하여, 자식 클래스에서의 구현을 강제한다.
  • Python에서는 abc라는 기본 라이브러리로 이와 관련한 기능을 지원한다.

composition

  • 다른 클래스의 특정 메서드만 이용하고 싶을 때는,
    상속보단 합성을 지향한다.
  1. 해당 클래스의 생성자 메서드에서 합성 대상 클래스의 인스턴스를 가져와,
    객체 변수에 저장한다.
  2. 해당 클래스에서는 위 객체 변수를 이용하여 메서드를 정의한다.

in Python

  • 다중 상속을 지원한다.
  • 기본적으로 overloading은 별도로 지원하지 않는다.
    • *args, **kargs를 사용한다.
    • multipledispatch 패키지의 @dispatch decorator를 통해서는 가능하다.
  • method overriding 시, 같은 type을 return하지 않아도 에러가 발생하지는 않는다.
    (하지만 같은 type을 return하는 것을 원칙으로 하는 게 좋을 것 같다.)

0개의 댓글