본문 바로가기

Python Basic/혼공파

[혼공파] Chapter 08 클래스


  • 는 개념 정리
  •  개인적으로 새롭게 알게 된 점 

8-1. 클래스의 기본

객체 지향 프로그래밍 (Object Oriented Programming)

  • 객체를 우선으로 생각해서 프로그래밍 한다는 의미. 
  • 프로그래밍에서 필요한 데이터를 추상화시켜, 상태와 행위를 가진 객체를 만들고, 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 언어. 

객체 (Object) & 추상화 (abstraction)

  • 객체: real world의 대상(object)을 소프트웨어 세계에 구현할 대상.
    • e.g. 사람이라는 현실의 객체를 소프트웨어 세계에 구현하였을 때, 소프트웨어 세계에 구현된 '사람'이 객체인 것.
  • (책에서 정의한 바) 여러 가지 속성을 가질 수 있는 대상. 
  • 추가적으로, real world 대상을 소프트웨어 세계에 구현할 때, 모든 데이터를 표현할 수는 없음. 따라서 프로그램에서 필요한 요소만을 사용해서 객체를 표현하는 것을 추상화 (abstraction) 라고 함. 
    • 즉, 복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능을 간추려 내는 것을 추상화 라고 함. 

클래스 (Class)

  • 객체를 구현하기 위한 설계도
  • 클래스는 CamelCase 규칙을 따름.

인스턴스 (Instance)

  • 이 설계도(Class)에 따라서 소프트웨어 세계에 구현된 실체
  • 설계도를 바탕으로 객체를 소프트웨어에 실체화 하면, 그것이 인스턴스이고, 이 과정을 인스턴스화 (instantiation) 라고 함.
  • 실체화된 인스턴스는 메모리에 할당 됨.

+추가) 가끔 객체와 인스턴스를 혼용해서 사용하여, 클래스 생성에 따라 메모리에 할당된 객체인 인스턴스를 '객체'라고 부르는데, 틀린 말은 아님. 인스턴스라고 부르는게 더 정확하지만, 개념적으로 인스턴스는 객체에 포함된다고 볼 수 있기 때문. 

 

생성자 (Constructor) & 메소드 (Method)

메소드 (Method)

  • 클래스가 가지고 있는 함수. 
  • 인스턴스와 관계되는 일을 하는 함수.
  • 인스턴스에서 메소드를 호출하기 위해서 . 연산자를 이용함. 

생성자 (Constructor)

  • 인스턴스 생성 시에 자동으로 호출됨.
  • (책 내용) 클래스 이름과 같은 함수, 즉 클래스 이름과 같은 인스턴스를 생성할 때 만드는 함수. 
  • 클래스 내부에 __init__ 라는 함수를 만들어, 객체를 생성할 때 처리할 내용을 작성할 수 있음. 

8-2. 클래스의 추가적인 구문

클래스를 사용하는 것은 작정하고 속성과 기능을 가진 객체를 만들겠다는 의미. 그래서 파이썬은 그에 따른 부가적인 기능을 지원함. 

isinstance()

  • 객체(인스턴스)가 어떤 클래스로부터 만들어졌는지 확인할 수 있도록 하는 함수. 
  • isinstance() 함수는 첫 번째 매개변수에 객체(인스턴스), 두 번재 매개변수에 클래스를 입력함. 
isinstance(인스턴스, 클래스)
  • 인스턴스가 해당 클래스를 기반으로 만들어졌다면 True, 전혀 상관이 없는 인스턴스와 클래스라면 False 리턴. 

isinstance(), type()

  • 단순한 인스턴스 확인이라면 type() 함수를 사용할 수도 있음. 
  • isinstance() 함수와 type() 함수로 확인하는 것의 차이
    • isinstance() 함수는 상속 관계까지 확인함.
    • type() 함수는 상속 관계를 확인하지 않음. 

  • isinstance() 함수를 사용하면, 이처럼 하나의 리스트로도 여러 종류의 데이터를 다룰 수 있음. 

특수한 이름의 메소드

__method__는 특수한 경우에 자동적으로 호출되는 함수라고 생각하면 됨. 

__init__ 메소드와 __str__ 메소드는 특별한 메소드. 객체를 문자열로 표현한 것을 반환함. 

 

__init__ 메소드

  • 객체 인스턴스화를 쉽게 해주는 __init__ 메소드.
  • 클래스 생성시 자동으로 실행되는 메소드.

+추가) __del__ 

  • 객체가 소멸할 때 자동으로 실행되는 메소드

__str__ 메소드

  • 디버깅할 때 유용한 __str__ 메소드.
  • 객체를 출력하면 파이썬은 __str__ 메서드를 호출함.
  • 즉, 클래스 자체의 내용을 출력하고 싶을 때, 형식을 지정하는 메소드.

  • 책에서는 str() 함수를 호출할 때 __str__() 함수가 자동으로 호출된다고 설명함. 
  • str() 함수를 호출할 때 뿐만 아니라, print() 함수 등을 사용해서 클래스 자체의 내용을 출력할 때도 __str__ 메소드가 사용됨. 

__init__, __str__ 메소드 외의 다른 함수들.

이름 영어 설명 연산자
eq equal 같다 ==
ne not equal 다르다 !=
gt greater than 크다 >
ge greater than or equal 크거나 같다 >=
lt less than 작다 <
le less than or equal 작거나 같다 <=
  • 비교 연산자 사용 시 자동으로 호출되는 메소드. 
  • return 으로 True, False를 반환함. 

 

클래스 변수와 메소드

인스턴스가 속성(변수)과 기능(함수)을 가질 수 있듯이,

클래스도 속성(변수)와 기능(함수)를 가질 수 있음. 

 

클래스 변수 & 인스턴스 변수

클래스 변수

  • 메서드 밖에 존재하는 변수. 이는 해당 클래스를 사용하는 모두에게 공용으로 사용되는 변수. 
  • 클래스 변수는 class 구문 바로 아래의 단계에 변수를 선언하면 됨. 
#클래스 변수 만들기
class Student:
    value = 0
#클래스 변수에 접근
Student.value
  • 클래스 변수에 접근하기 위해서, 클래스 이름.변수 이름 사용.
    • 클래스 내부와 외부에서 클래스 변수에 접근할 때는 모두 (클래스 이름.변수 이름) 의 형태로 접근함. 

+추가) 인스턴스 변수

self가 붙어 있는 변수는 인스턴스 변수. 

  • 클래스 변수는 클래스의 네임스페이스에 위치하며, 인스턴스 변수는 인스턴스의 네임스페이스에 위치함.

클래스와 인스터스 비교 설명 GOOD 

wikidocs.net/1743

 

위키독스

온라인 책을 제작 공유하는 플랫폼 서비스

wikidocs.net

클래스 함수

* 파이썬에서는 클래스에서 직접 접근할 수 있는 메소드가 세 가지 있음. *

  • +추가) instance method (인스턴스 메서드)
  • +추가) static method (정적 메서드)
  • class method (클래스 메서드-> 책에서 말하는 클래스 함수가 classmethod)

1. 인스턴스 메서드

  • 가장 흔히 쓰이는 인스턴스 메서드는 인스턴스 변수에 접근 할 수 있도록, 메서드의 첫 번째 파라미터에 항상 객체 자신을 의미하는 'self' 파라미터를 가짐. 인스턴스 메서드는 여러 파라미터를 가질 수 있지만, 첫 번째 파라미터는 항상 self를 가짐. 
  • 해당 메서드는 호출한 객체에만 영향을 미침. 
  • 객체 속성에 접근이 가능함. 
  • 호출 방법
    • 해당 클래스 안에서는 self.메서드명
    • 클래스 밖에서는 객체.메서드명
class Test:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def print_info(self):
        print(self.name, ',', self.age) #1

    def test_func(self):
        self.print_info() 

test1 = Test('hong', 22)
test1.print_info() #2  결과값 : hong , 22 
test1.test_func() #3 결과값 : hong , 22

2. 정적 메서드

  • 인스턴스를 생성하지 않고도 호출하는 메서드.
  • 객체와 독립적이지만, 로직상 클래스 내에 포함되는 메서드. 
  • self 파라미터를 가지고 있지 않음. 따라서 인스변스 변수에 액세스가 불가능.
    • 그러나, 정적 메서드 내부에서 클래스 변수에는 클래스명.클래스 속성명 으로 액세스가 가능함. 
  • 클래스에서 직접 접근할 수 있는 메소드. 파이썬에서는 다른 언어와는 다르게 정적메소드임에도 불구하고, 인스턴스에서도 접근이 가능함. 정적 메서드는 특별히 추가되는 인자가 없음. 
  • @staticmethod라는 데코레이터를 붙여서 해당 메서드가 정적 메서드임을 표시함. 
class Calc:

    count = 10 # 클래스 변수(클래스 속성)

    @staticmethod
    def add(a):
        print(a + Calc.count) # 클래스 속성에는 엑세스가 가능하다.

    @staticmethod
    def mul(a):
        print(a * Calc.count)

Calc.add(15) # 결과값 :25 
Calc.mul(15) # 결과값 : 150
class StringUtils:
    @staticmethod
    def toCamelcase(text):
        words = iter(text.split("_"))
        return next(words) + "".join(i.title() for i in words)

    @staticmethod
    def toSnakecase(text):
        letters = ["_" + i.lower() if i.isupper() else i for i in text]
        return "".join(letters).lstrip("_")
  • 정적 메서드는 유틸리티 메서드를 구현할 때 많이 사용됨.
    • e.g. StringUtils 클래스는 2개의 정적 메서드로 이뤄짐. toCamelCase 메서드는 snake_case 문자열을 CamelCase 로 변환, toSnakecase는 그 역방향으로 변환. 이 두 개의 메서드는 매개 변수로 넘어온 문자열에만 의존하는 순수한 (pure) 함수이기 때문에 굳이 클래스의 이루로 선언할 필요는 없지만, 이렇게 비슷한 류의 여러 유틸리티 메서드를 하나의 클래스로 묶어두고 싶을 때 정적 메서드로 선언.

3. 클래스 메서드

  • 클래스 메서드는 첫 번째 인자로 클래스(cls) 를 입력함. 
    • 첫번째 매개변수로 클래스 인스턴스가 아닌, 클래스 자체가 넘어오는 것.
    • 클래스 메서드는 이 cls를 통해 클래스 속성 (attribute)에 접근하거나, 클래스 메서드 호출. 
    • 그러나 인스턴스 메서드와 달리 인스턴스 속성에 접근하거나 다른 인스턴스 메서드를 호출 하는 것은 불가능 (self 가 없으니까)
  • 인스턴스 없이 호출이 가능하다는 점에서 정적 메서드와 비슷하지만, cls인자가 추가된다는 점에서 차이점이 있음. 
  • cls
    • e.g. hello 클래스의 num 속성에 접근하기 위해서는?
#staticmethod
class hello:
    num = 10

    @staticmethod
    def calc(x):
        return x + 10 + hello.num

print(hello.calc(10))
#결과
30
  • 정적 메서드: 객체로 접근하는 것이 아니기 때문에, self.num을 사용할 수 없음. 따라서 hello.num 의 정적 변수로 접근함.  
#classmethod
class hello:
    num = 10

    @classmethod
    def calc(cls, x):
        return x + 10 + cls.num

print(hello.calc(10))
#결과
30
  • 클래스 메서드: cls로, 클래스의 어떤 속성에도 접근할 수 있음. 이 경우 cls.num을 통해 hello 클래스의 num 속성에 접근함. 

+추가) 상속 관계가 있는 클래스들에서는 cls가 가리키는 클래스는 상속 받은 클래스임.

class hello:
    t = '내가 상속해 줬어'

    @classmethod
    def calc(cls):
        return cls.t

class hello_2(hello):
    t = '나는 상속 받았어'

print(hello_2.calc())

#결과
나는 상속 받았어

 

좀 더 알아보기

1. 가비지 컬렉터

2. 프라이빗 변수와 게터/세터

3. 상속

 

가비지 컬렉터

  • 컴퓨터가 일을 할 때, 처리할 정보들을 공간이 필요함. 공간 = 메모리. 
  • 코드를 작성하고, 프로그램을 실행하면서 데이터(변수, 함수, 객체 등)가 메모리에 올라가고, 메모리가 가득 차는 것을 방지할 필요가 있음. => 더 이상 사용할 가능성이 없는 데이터를 메모리에서 제거하는 역할: 가비지 컬렉터. 
    • 메모리를 비우지 못해서 발생하는 문제를 '메모리 누수', 'memory leak'이라고 함. 
    • C/C++ 언어에서는 데이터를 메모리에서 제거하는 코드를 직접 작성해야 했는데, 자바를 비롯한 새로운 언어에서 가비지 컬렉터 도입. 
  • 메모리를 알아서 관리하는 언어 = managed language <-> unmanaged language
  • 가비지 컬렉터 작동 방식
    • mark-and-sweep: 아직 필요한 것들만 마크한 다음에 마크 안 된 것들은 갖다버리는 방식. 
      • 프로그래밍 측면에서, 루트에서 닿지 않는 변수들을 치우는 것. 
    • reference counting (참조 카운팅): 한 요소가 다른 요소에게 몇 번 참조되는지 세어서, 그 수가 0이 되면 치우는 것. 
  • 메모리 누수를 방지하는 방식은 언어의 특성마다 다름. 따라서 사용하는 언어나 플랫폼 등에 따라 바람직한 메모리 관리 방식을 찾아볼 필요가 있음. 

프라이빗 변수와 게터/세터

private(비공개) & pulbic(공개)

 

private 멤버: 클래스 안에서만 접근가능한 멤버

public 멤버: 클래스 안과 밖에서 모두 접근가능한 멤버

  • 메서드에서도 public, private 속성 적용이 가능함. 

public을 사용할 때: _ _변수명_ _

private을 사용할 때: _ _변수명 

  • 사실 정확하게 말하면, 파이썬에는 public과 private 이란 개념이 없지만, 이와 같이 변수의 이름을 가지고 그것과 비슷한 기능을 표현할 수 있음. 

public 변수
private

  • cTest 객체에는 __test_var라는 변수가 없다고 함, 이와 같이 private 과 비슷한 효과를 볼 수 있음. 

(책 내용) 파이썬은 클래스 내부의 변수를 외부에서 사용하는 것을 막고 싶을 때, 인스턴스 변수 이름을 __변수이름 형태로 선언(언더바 2개).

 

=> private 변수에 접근하고 싶을 때, getter & setter 사용. 

 

getter & setter (데코레이터)

파이썬 클래스에서 메서드를 통하여 속성의 값을 가져오거나, 저장하는 경우가 있음. 이 때 값을 가져오는 메서드를 getter, 값을 저장하는 메서드를 setter라고 함. 

 

CODE 1

    def __init__(self):
        self.__age = 0
 
    def get_age(self):           # getter
        return self.__age
    
    def set_age(self, value):    # setter
        self.__age = value
 
james = Person()
james.set_age(20)
print(james.get_age())

OUTPUT 1

20

 

CODE 2 (getter, setter)

class Person:
    def __init__(self):
        self.__age = 0
 
    @property
    def age(self):           # getter
        return self.__age
 
    @age.setter
    def age(self, value):    # setter
        self.__age = value
 
james = Person()
james.age = 20      # 인스턴스.속성 형식으로 접근하여 값 저장
print(james.age)    # 인스턴스.속성 형식으로 값을 가져옴

OUTPUT 2

20
  • getter와 setter 메서드의 이름은 모두 age. 또한 getter에는 @property가 붙어있고, setter에는 @age.setter가 붙어있음. 즉, 값을 가져오는 메서드에는 @property 데코레이터를 붙이고, 값을 저장하는 메서드에는 @메서드이름.setter 데코레이터를 붙임. 
  • @property와 @age.setter를 붙이면, james.age 처럼 메서드를 속성처럼 사용할 수 있음. 값을 저장할 때, 메서드에 바로 값을 할당하면 되고, 값을 가져올 때도 메서드에 바로 접근하면 됨. 

상속 (inheritance) & super()

  • 프로그래밍 언어는 기반이 되는 것은 부모 (parent)라고 부르고, 이를 기반으로 생성한 것을 자식 (child)라고 부름. 부모가 자식에게 자신의 기반을 물려주는 기능을 '상속'이라고 함. 
  • 클래스의 상속 기능을 사용하면, 부모 클래스에서 만들어둔 기능(메서드)과 속성(변수)을 물려받을 수 있음.

상속
상속

 

  • (책 내용) 상속은 기존에 있는 클래스를 기반으로 조금 수정해서, 내가 원하는 클래스를 만들 때 사용. 
  • 부모에 정의되어 있는 함수를 자식에서 다시 정의하는 것을 재정의, 오버라이드 (override) 라고 함. 

super()

  • 부모 클래스의 이름을 알고 있을 경우 Person.__init__과 같이 부모 클래스의 이름과 . 을 사용하여 부모클래스의 메소드를 호출 할 수 있음.
  • super() 를 통해 부모 클래스의 메소드를 손쉽게 이용할 수 있음. 
  • 부모 클래스를 명시적으로 적어줄 필요가 없으므로 프로그램의 유지 보수가 쉬움. 

  • super() 에서는 self를 사용할 필요가 없음. 
  • 실행 기능을 똑같음. 

끝.

'Python Basic > 혼공파' 카테고리의 다른 글

나머지 공부  (0) 2021.01.26
[혼공파] Chapter 07 모듈  (0) 2021.01.20
[혼공파] Chapter 06 예외 처리  (0) 2021.01.13
[혼공파] Chapter 05 ③함수 고급  (0) 2021.01.12
[혼공파] Chapter 05 ②함수의 활용  (0) 2021.01.12