[포스코 신재생에너지 IoT 개발자 5기] Python 15편 — 클래스(하)

Doohee·2025년 11월 30일
post-thumbnail

상편에서 클래스의 골격(변수·메서드 종류)을 봤다면,
하편에서는 “설계 관점에서 클래스” 를 다룬다.

  • 데이터 보호: 정보 은닉, 캡슐화

  • 접근 수준: public / protected / private

  • 안전한 접근: Getter / Setter, @property

  • 재사용/확장: 상속·오버라이딩·super()

  • 인터페이스 강제: 추상 클래스

1. 정보 은닉(Information Hiding)과 캡슐화(Encapsulation)

1) 정보 은닉

  • 객체의 내부 상태(데이터)에 외부에서 직접 접근하지 못하게 숨기고, 메서드를 통해서만 접근하게 만드는 설계 기법.

  • 목적:

    • 잘못된 값 대입을 막아 데이터 무결성 보호

    • 내부 구현을 바꾸더라도 외부 코드와의 의존성 최소화

2) 캡슐화

  • 관련 있는 데이터(속성)와 기능(메서드)를 하나의 단위(클래스)에 묶고, 외부에는 필요한 인터페이스만 공개하는 것

  • 정리:

    • 정보 은닉 = 캡슐화를 실현하는 구체적 기법 중 하나

    • "내부는 숨기고, 외부에는 최소한의 문만 연다"는 구조

2. 접근 수준 - public / protected / private (파이썬 방식)

파이썬은 public / private 키워드가 없다. 대신, 이름 앞에 붙는 언더스코어 규칙으로 표현한다.

설명 ✔ 언더스코어 규칙으로 public / protected / private를 구분하는 파이썬의 접근 제어 방식

1) public 멤버(기본)

  • 별도 언더스코어 없이 정의된 속성 / 메서드

  • 클래스 외부에서 자유롭게 접근 가능

설명 ✔ 언더스코어 없이 선언된 속성·메서드는 외부에서 자유롭게 접근 가능함을 보여주는 예시

2) protected 멤버: _변수명

  • _변수명 처럼 언더스코어 1개로 시작

  • 문법적으로 막히지는 않지만, "직접 건드리지 말고, 자식 클래스에서 주로 사용하자"는 관례

설명 ✔ 언더스코어 1개로 ‘자식 전용’ 의미를 나타내는 관례 기반 protected 패턴

3) private 멤버: __변수명 (네임 맹글링)

  • 언더스코어 2개(__)로 시작

  • 내부적으로 _클래스이름__변수명으로 이름이 바뀜 (네임 맹글링)

  • 그대로 접근 시 에러

  • 의도:

    • 실수로 내부 구현을 건드리지 않도록 접근을 어렵게 만드는 장치

    • 의도적으로 우회할 수 있지만, 그 순간 캡슐화를 깨는 것이라는 신호

설명 ✔ __name이 내부적으로 _클래스명__name으로 변환되는 네임 맹글링 구조

3. Getter / Setter 메서드와 @property

1) Getter / Setter 기본 형태

  • 내부 상태는 __balance로 숨김

  • 읽기 / 쓰기 작업은 메서드로만 가능하도록 강제

  • 이 과정에서 검증 로직 삽입 가능

설명 ✔ private 변수를 메서드를 통해 안전하게 읽고 쓰도록 강제하는 구조

2) @property 사용

  • 메서드를 "속성처럼" 보이게 만드는 문법

  • 장점:

    • 외부에서는 일반 속성처럼 사용

    • 내부에서는 함수처럼 로직(검증, 로그 변환 등)을 자유롭게 추가·수정

설명 ✔ 속성처럼 보이지만 내부적으로 함수 호출로 검증·제어를 수행하는 property 접근 방식 설명 ✔ 값 변경 시 검증 로직을 실행하여 잘못된 데이터 입력을 막는 setter 구조

실습1. 접근 제어와 정보은닉 연습

문제1) UserAccount 클래스: 비밀번호 보호

  • UserAccount 클래스를 정의하세요.

  • 인스턴스 변수:

    • username: 사용자 이름

    • __password: private 변수로, 비밀번호 저장

  • 생성자에서 사용자 이름과 비밀번호를 초기화하세요.

  • 다음 메서드를 정의하세요.:

    • change_password(old_pw, new_pw): 현재 비밀번호가 old_pw와 같을 때만 변경 허용,
      틀리면 "비밀번호 불일치" 출력

    • check_password(password): 비밀번호 일치 여부를 반환(True / False)

설명 ✔ 비밀번호를 private으로 숨기고 메서드로만 변경·검증 가능하게 만든 정보 은닉 연습 문제

문제2) Student 클래스: 성적 검증(@property 사용)

  • Student 클래스를 정의하세요.

  • 인스턴스 변수 __score는 private으로 선언합니다.

  • score에 대한 getter / setter를 @property를 사용하여 정의하세요.

    • 점수는 0 이상 100 이하만 허용되며, 범위를 벗어나면 ValueError를 발생시킵니다.
설명 ✔ 점수 검증을 property로 처리하여 값 범위를 강제하는 학생 클래스 예시

4. 상속(Inheritance) - 코드 재사용과 확장

1) 개념

  • 기존 클래스(부모, 상위 클래스)의 속성과 메서드를 새로운 클래스(자식, 하위 클래스)가 물려받아 사용하는 것

  • 필요성:

    • 공통 기능은 부모에 모아두고, 자식 클래스는 차이점만 구현 ⇒ 중복 감소, 유지보수 용이

    • 같은 인터페이스로 다양한 타입을 다루는 다형성 기반

설명 ✔ 부모 클래스의 기능을 자식이 물려받아 확장하는 상속 관계 개념도

2) 기본 문법

설명 ✔ class Child(Parent) 형태로 구성되는 기본 상속 문법 설명 설명 ✔ 부모 기능을 그대로 활용하면서 자식 객체가 동작하는 실행 흐름 예시

5. super()를 이용한 부모 생성자 / 메서드 호출

1) 개념

  • super()는 부모(상위) 클래스의 메서드를 호출하기 위한 내장 함수

  • 상속 계층이 깊거나 다중 상속 상황에서도 MRO(Method Resolution Order)를 따라 올바른 부모 메서드를 찾아 호출

설명 ✔ MRO 기반으로 부모 메서드를 찾아 호출하는 super()의 동작 방식 설명

2) 생성자에서의 사용

  • 자식 생성자에서 super().__init__(...)를 호출하지 않으면 부모 측에서 설정하던 속성이 초기화되지 않을 수 있음
설명 ✔ 자식 생성자에서 부모 생성자를 호출하여 초기화를 확장하는 예시

3) 일반 메서드에서의 사용

설명 ✔ 부모 메서드 실행 후 자식 동작을 덧붙여 기능을 확장하는 패턴

4) super() 관련 주의사항

  • super()는 클래스 내부 메서드에서 사용하는 것이 원칙

  • 보통 생성자에서 super().__init__()형태로 가장 많이 사용

  • 다중 상속 등에서 부모클래스명.메서드(self, ...)를 직접 호출하면 MRO를 무시하게 되어 예기치 못한 동작 가능

    ⇒ super() 권장

6. 메서드 오버라이딩(Method Overriding)

개념

  • 부모 클래스에 이미 정의된 메서드를 자식 클래스에서 같은 이름, 같은 인자로 다시 정의하여 동작을 바꾸는 것

  • 같은 메서드를 호출해도, 어떤 자식 클래스 인스턴스냐에 따라 동작이 달라지는 것이 다형성

설명 ✔ 같은 메서드 이름을 자식에서 다시 정의해 타입별 동작을 다르게 만드는 구조

실습2. 상속과 오버라이딩 실습

문제) Shape 클래스 오버라이딩

[Shape 클래스 조건]

  • 생성자를 통해 다음 두 값을 초기화하세요.

    • 변의 개수(sides)

    • 밑변의 길이(base)

  • printinfo()메서드를 정의하여 다음과 같이 출력

    • 변의 개수: 4

    • 밑변의 길이: 10

  • area()메서드를 정의하여 "넓이 계산이 정의되지 않았습니다."라는 메시지 출력

    • 자식 클래스에서 이 메서드를 오버라이딩해야 합니다.

[Rectangle 클래스 조건]

  • Shape를 상속받습니다.

  • 생성자에서 sides, base, height를 모두 초기화합니다.

  • area()메서드를 오버라이딩하여 base × height 값을 출력합니다.

[Triangle 클래스 조건]

  • Shape를 상속받습니다.

  • 생성자에서 sides, base, height를 모두 초기화합니다.

  • area()메서드를 오버라이딩 하여 (base × height) / 2 값을 출력합니다.

[실행]

  • Rectangle과 Triangle 객체를 생성합니다.

  • 각 객체에 대해 printinfo()와 area() 메서드를 차례로 호출하세요.

설명 ✔ 부모 Shape의 area 메서드를 자식에서 오버라이딩하여 구현하는 실습 예시

7. 추상 클래스(Abstract Class)

1) 개념

  • 직접 인스턴스를 만들지 않고, 공통 인터페이스를 정의하는 용도로 사용하는 클래스

  • 특징:

    • 일부 메서드는 구현 없이 형태만 정의(추상 메서드)하고, 실제 구현은 자식 클래스에 강제

    • "이 메서드는 반드시 구현되어야 한다."는 설계를 코드로 표현

2) 파이썬에서의 추상 클래스 - abc 모듈

  • ABC를 상속 ⇒ 추상 클래스가 됨

  • @abstractmethod가 붙은 메서드는 자식에서 반드시 구현해야 함

  • 추상 메서드를 그대로 둔 채 인스턴스화 시도 시 ⇒ TypeError

3) 추상 클래스 기본 문법

  • from abc import ABC, abstractmethod

  • class Base(ABC): 형태로 추상 클래스 선언

  • 추상 클래스를 직접 인스턴스화하는 것은 불가능

  • 추상 메서드를 모두 구현한 구체 클래스(concrete class)만 인스턴스 생성 가능

설명 ✔ 추상 클래스가 인스턴스화 불가하며 템플릿 역할을 수행한다는 개념도 설명 ✔ 자식 클래스에 구현을 강제하는 추상 메서드의 동작 예시 설명 ✔ 추상 메서드를 구현하지 않으면 TypeError가 발생하는 실행 예시

실습3. 추상 클래스 연습문제

문제) 추상 클래스 Payment 구현

[아래 조건을 만족하는 클래스를 구현하세요.]

  • 추상 클래스 Payment를 정의하고, pay(amount)를 추상 메서드로 선언하세요.(abc 모듈 사용)

  • CardPayment 클래스와 CashPayment 클래스는 Payment를 상속받아 pay() 메서드를 오버라이딩 하세요.

    • CardPayment: 카드로 {amount}원을 결제합니다. 출력

    • CashPayment: 현금으로 {amount}원을 결제합니다. 출력

설명 ✔ 공통 결제 인터페이스를 추상 클래스로 정의하고 구체 클래스로 구현한 예시

8. 실무 예시

예시1) 결제 인터페이스 공통화

  • Payment 인터페이스 기준으로 프로세스 작성

  • 새 결제 수단 추가 시 Payment 상속 + pay() 구현만 하면 됨 ⇒ 기존 코드 수정 최소화

설명 ✔ 추상 클래스 Payment를 기반으로 카드·계좌이체 결제 로직을 오버라이딩한 구조 예시

예시2) 에너지 센서 추상화

  • 다양한 센서 타입(Power, Temp, Humidity 등)을 하나의 인터페이스로 처리

  • 분석 / 수집 코드가 BaseSensor 기준으로 단순해짐

설명 ✔ BaseSensor 추상 클래스를 기준으로 다양한 센서(Power·Temperature)를 동일한 인터페이스로 수집하는 구조 예시

9. 클래스(하) 한눈에 보기

  • 정보 은닉: 내부 상태를 직접 노출하지 않고, 메서드 / @property 를 통해서만 접근

  • 캡슐화: 속성과 메서드를 하나의 단위로 묶고, 필요한 인터페이스만 외부에 제공

  • 접근 수준 (파이썬 컨벤션)

    • public : name

    • protected : _name

    • private : __name (네임 맹글링)

  • @property: 밖에서는 속성처럼 보이지만, 내부에서는 함수 호출로 검증·로그 등 수행

  • 상속: 공통 기능 재사용, 자식에서 차이점만 구현

  • super()

    • 부모 생성자·메서드 호출

    • MRO 기반으로 올바른 상위 구현 호출

  • 오버라이딩: 같은 이름의 메서드를 자식에서 다시 정의하여, 타입별로 다른 동작 구현

  • 추상 클래스

    • 인터페이스를 강제하는 틀

    • @abstractmethod 로 “반드시 구현해야 하는 메서드” 지정

10. 아웃트로 - 클래스 단원 전체 정리

  • 클래스 정의와 기본 문법

  • 인스턴스/클래스/정적 메서드

  • 정보 은닉·캡슐화, 접근 수준

  • @property 를 이용한 안전한 접근

  • 상속, super(), 오버라이딩

  • 추상 클래스와 인터페이스 설계

까지 전부 정리했다.

이제부터는:

  • 작은 문제라도 클래스로 설계해 보는 연습

  • @property, 상속, 추상 클래스 등을 실제 코드에 적용

  • 에너지·IoT·데이터 분석 도메인에 맞는 클래스를 직접 설계

를 반복하면,

“문법으로서의 클래스”를 넘어서 “설계 도구로서의 클래스” 를 다루게 된다.

profile
에너지 기획 전문가로 성장하고자 합니다.

0개의 댓글