위클리 페이퍼는 현재 훈련받고 있는 코드잇 스프린트 데이터 애널리스트 트랙에서 매주마다 훈련생 스스로 프로그래밍 언어, 데이터분석, 통계, 머신러닝 등 특정 주제에 대하여 심화 학습을 할 수 있도록 제출하는 과제입니다.
(매주 2~3가지 주제를 스스로 알아보고 학습하여 관련된 내용을 정리하여 후에 취업 활동 간에 경험할 수 있는 기술 면접을 대비함)
3주차에 이어서 이번 4주차 위클리 페이퍼의 내용을 소개하려고 합니다.
이번 4주차 위클리 페이퍼 주제는
1. 클래스와 인스턴스에 대해 설명해주세요.
2. 정적 메소드는 무엇이고, 어떻게 호출하나요?
이번 4주차 위클리 페이퍼의 첫 주제, 클래스와 인스턴스는 객체 지향 프로그래밍에서 중요한 개념입니다.
객체 지향 프로그래밍(OOP, Object-Oriented Programming)이란 프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체로 만들고, 객체들간의 상호작용을 통해 로직을 구성하는 명령형 프로그래밍 방법입니다.
만약, 객체 지향 프로그래밍을 잘 활용한다면 좋은 프로그래밍으로 프로그램을 더 빨리 만들 수 있고, 나중에 수정하기에도 편하다고 합니다.
하지만 객체 지향 프로그래밍이 파이썬에서 꼭 적용해야 하는 프로그래밍은 아니며, 분석가나 개발자가 보다 복잡한 프로그래밍을 하는데 도움이 되는 방법이라는 점만 알고 넘어가면 좋을 것 같습니다.
본격적인 내용을 설명하기 전에, 객체 지향 프로그래밍에 대한 개념도 후에 기술 면접이나 여러 자리에서 설명할 상황이 생길 수 있기 때문에객체 지향 프로그래밍의 장, 단점을 간단하게 짚고 넘어가려고 합니다.
객체 지향 프로그래밍(OOP, Object-Oriented Programming)의 장, 단점
장점
- 재사용성
클래스와 객체를 이용하여 한 번 작성된 코드를 여러 곳에서 재사용할 수 있고 다른 사람이 만든 코드를 사용하여 코드의 중복을 줄이고 유지보수를 용이하게 합니다. - 추상화
복잡한 시스템을 추상화하여 중요한 부분만 노출하고, 내부 구현을 감추는 방식으로 프로그래밍을 단순화하여 복잡한 문제를 쉽게 이해하고 관리할 수 있습니다. - 다형성
객체들이 서로 다른 방식으로 동작하도록 할 수 있으며, 같은 인터페이스를 공유하는 객체들을 동일하게 처리할 수 있어 코드의 유연성과 확장성을 높입니다. - 상속
기존 클래스의 속성과 메서드를 재사용하고, 새로운 클래스에서 이를 확장하여 사용할 수 있어 코드의 재사용성과 계층 구조를 통한 논리적 설계를 할 수 있습니다. - 캡슐화
데이터와 메서드를 하나의 객체로 묶고, 외부에서 접근할 수 없도록 제한함으로써 데이터의 무결성을 유지할 수 있으며, 이는 코드의 안정성과 보안성을 높입니다.
단점
- 성능 저하
객체 간의 메시지 전달, 상속 계층 구조 탐색 등으로 인해 절차적 프로그래밍에 비해 성능이 저하되고, 처리 속도가 느려질 수 있습니다. - 초기 설계의 어려움
초기 설계 단계에서 많은 시간을 투자해야 하기에 어려움이 있고 객체, 클래스, 상속 구조 등을 미리 잘 설계하지 않으면 이후에 수정하기 어렵고 비용이 많이 들 수 있습니다. - 복잡한 상속 구조
상속을 잘못 사용하면 클래스 간의 의존성이 증가하고, 이를 수정하거나 확장하기 어려운 구조가 될 수 있습니다.
객체 지향 프로그래밍은 코드의 재사용성을 높이고, 복잡한 시스템을 추상화하여 관리하기 쉽게 만드는 등 많은 장점을 가지고 있습니다.
하지만 설계와 구현이 복잡할 수 있고, 성능 저하와 처리 속도 증가 등의 단점도 존재하기에 장단점을 잘 숙지하고 적절히 활용하는 것이 중요합니다.
객체 지향 프로그래밍에서 알고 가야 하는 중요한 5가지 개념
- 클래스(Class): 객체를 생성하기 위한 설계도.
- 객체(Object): 클래스로부터 생성된 인스턴스.
- 상속(Inheritance): 클래스가 다른 클래스의 속성과 메서드를 물려받는 기능.
- 다형성(Polymorphism): 동일한 메서드가 다른 객체에서 다르게 동작하는 기능.
- 캡슐화(Encapsulation): 객체의 데이터를 숨기고, 메서드를 통해 데이터에 접근하고 조작하는 기능.
객체 지향 프로그래밍(OOP)에서 중요한 핵심 개념 5가지는 객체 지향 프로그래밍의 장점을 극대화하고 시스템을 보다 구조적으로 설계하고 유지보수하는 데 중요한 역할을 합니다.
이러한 OOP에 대한 내용을 뒤로 하고 이제 클래스와 인스턴스에 대해 자세히 설명하도록 하겠습니다.
1. 클래스와 인스턴스에 대해 설명해주세요.
앞에서 객체 지향 프로그래밍에 대해 설명을 했으니 클래스와 인스턴스가 어떤 것들인지 설명해서 이해하게 되면 객체 지향 프로그래밍을 더 잘 이해할 수 있을 것 같습니다.
우선, 클래스와 인스턴스가 무엇인지부터 설명하겠습니다.
클래스와 인스턴스의 개념
클래스
클래스(Class)는 객체(인스턴스)를 생성하기 위한 설계도 혹은 틀입니다.
즉, 클래스는 객체를 생성해주는 생성자, 객체가 공통적으로 가지는 속성, 공통적인 기능(함수)들을 정의합니다.
클래스는 데이터(속성)와 메서드(함수)를 포함하고 있습니다.
클래스를 정의할 때는 class 키워드를 사용합니다.
예를 들어, '자동차'이라는 클래스가 있다면, 그 클래스에는 제조사, 모델명, 제조 연도, 색상같은 데이터와 가속(accelerate), 브레이크(brake), 경적(honk) 같은 동작을 나타내는 메서드가 포함될 수 있습니다.
- 속성(Attribute) 또는 멤버 변수(Member Variable): 클래스가 가지는 데이터를 의미합니다.
예를 들어, '사람' 클래스에서는 이름, 나이, 성별 등이 속성이 될 수 있습니다. - 메서드(Method) 또는 멤버 함수(Member Function): 클래스 안에서 구현하며 클래스가 수행할 수 있는 동작을 정의한 함수입니다.
메서드의 첫 번째 파라미터는 클래스의 인스턴스 자신이 됩니다. 따라서 self라는 이름의 파라미터를 주로 사용합니다.
예를 들어, '사람' 클래스에서는 먹다, 잠자다, 일하다 등이 메서드가 될 수 있습니다.
인스턴스(객체의 일종)
인스턴스(Instance)는 클래스를 기반으로 실제로 메모리에 할당된 소프트웨어에 실체화된 구체적인 객체를 의미합니다.
클래스(class)의 객체(object)가 소프트웨어에 실체화되면 이제 그것을 인스턴스(instance)라고 부릅니다.
인스턴스는 클래스를 호출하여 생성됩니다. 이 과정에서 생성자 메서드(__init__)가 호출되어 인스턴스의 속성을 초기화합니다.
(클래스로부터 만들어진 개별 객체, 클래스에 선언된 모양 그대로 생성된 실체)
예를 들어, '자동차' 클래스에서 설계도를 바탕으로 생성된 실제 자동차(객체)가 그 클래스의 인스턴스가 됩니다.
각각의 인스턴스는 서로 다른 데이터를 가질 수 있지만, 모두 같은 클래스에 기반하고 있습니다..
간단히 말해서, 클래스는 객체를 생성하기 위한 템플릿이고, 인스턴스는 그 템플릿을 기반으로 실제로 만들어진 개별 객체를 말합니다.
클래스와 인스턴스의 관계
이해가 더 쉽도록 클래스와 인스턴스의 관계를 설계도와 실제 제품의 관계에 비유하여 설명할 수 있습니다.
클래스는 객체를 만들기 위한 설계도(청사진)이고, 인스턴스는 그 설계도를 기반으로 실제로 생성된 객체입니다.
- 한 클래스, 여러 인스턴스: 하나의 클래스는 여러 개의 인스턴스를 생성할 수 있습니다. 예를 들어, 자동차(Car)라는 클래스가 있다면, 이 클래스로부터 여러 개의 자동차 인스턴스를 만들 수 있습니다.
- 공유된 구조: 클래스에서 정의된 속성과 메서드는 모든 인스턴스가 공유합니다. 즉, 모든 인스턴스는 동일한 구조를 가집니다.
- 개별 데이터: 각 인스턴스는 독립적인 데이터를 가질 수 있습니다. 예를 들어, 자동차 클래스의 인스턴스인 myCar와 yourCar는 각각 다른 색상, 모델명, 속도 등을 가질 수 있습니다.
클래스와 인스턴스를 사용하는 이유
클래스와 인스턴스를 사용하는 이유는 코드의 재사용성 및 유지보수성을 높이고, 복잡한 시스템을 더 쉽게 이해하고 관리할 수 있도록 하기 위함입니다. 게다가, 위에서 설명한 객체 지향 프로그래밍(OOP)은 이러한 목적을 달성하는 데 매우 효과적입니다.
- 코드의 재사용성
클래스를 사용하면 한 번 작성된 코드를 여러 곳에서 재사용할 수 있습니다.
예를 들어, Car 클래스를 정의하면, 이 클래스를 기반으로 여러 개의 자동차 객체를 생성할 수 있습니다.
새로운 객체를 만들 때마다 같은 코드를 반복해서 작성할 필요가 없습니다. - 유지보수성
클래스와 인스턴스를 사용하면 코드를 논리적으로 구조화할 수 있습니다.
예를 들어, 자동차와 관련된 모든 속성 및 메서드를 클래스 안에 모아 두면, 자동차와 관련된 코드를 수정하거나 추가하기가 쉬워집니다. - 상속
상속을 통해 기존 클래스를 확장하여 새로운 기능을 추가할 수 있습니다.
예를 들어, 전기차 클래스를 자동차 클래스의 서브클래스로 정의하여, 전기차에 특화된 기능을 추가하여 사용할 수 있습니다. - 복잡한 모델링이 가능하다
클래스와 인스턴스를 사용하면 현실 세계의 객체와 그 상호작용을 코드로 모델링할 수 있습니다.
예를 들어, 은행 계좌, 고객, 거래 등의 객체를 클래스로 정의하고, 이들 간의 상호작용을 구현할 수 있습니다.
즉, 클래스와 인스턴스를 사용하면 코드의 재사용성과 유지보수성을 높이고, 복잡한 시스템의 모델링을 쉽게 할 수 있습니다.
또한 상속과 다형성을 통해 코드의 유연성과 확장성을 높일 수 있습니다.
이러한 이유로 클래스와 인스턴스를 활용한 객체 지향 프로그래밍은 복잡한 소프트웨어 시스템을 개발하는 데 매우 유용한 패러다임입니다.
2. 정적 메소드는 무엇이고, 어떻게 호출하나요?
정적 메소드는 클래스의 인스턴스(객체)가 아닌 클래스 자체에 속하는 메소드입니다.
다시 말해 인스턴스와 클래스에 관련된 내용이 전혀 필요하지 않은 메소드입니다.
정적 메소드를 통해 객체를 생성하지 않고도 클래스 이름을 통해 클래스를 쉽게 직접 호출할 수 있습니다.
정적 메소드는 클래스 메소드와 비슷하게 데코레이터를 사용해주어야 하며, @staticmethod 데코레이터를 사용하여 정의됩니다.
이는 클래스의 인스턴스와는 독립적으로 동작하며, 클래스 이름을 통해 직접 호출할 수 있습니다.
요약하자면, 정적 메소드는 클래스의 기능을 보완하거나 독립적인 유틸리티 함수를 제공할 때 유용하며, 클래스의 상태나 인스턴스의 상태와 무관한 기능을 구현할 때 사용됩니다.
# 예시
@staticmethod
class MathUtils:
def add(a, b):
return a + b
# 정적 메소드 호출
result = MathUtils.add(5, 3)
print(result) # 출력: 8
주요 특징
- 클래스와 관련 있지만 인스턴스와는 관련이 없습니다.
- 클래스의 상태나 속성에 접근할 필요가 없는 기능을 구현할 때 사용합니다.
- 인스턴스의 속성에 접근할 필요가 없으므로 첫번째 인수로 self나 cls를 받지 않습니다.(자동으로 전달되는 파라미터가 필요가 없다.)
- 정적 메소드는 클래스의 인스턴스를 생성하지 않고도 클래스의 이름을 통해 직접 호출할 수 있습니다.
정적 메소드와 클래스 메소드의 차이
- 정적 메소드(@staticmethod)
클래스와 인스턴스의 속성이나 메소드에 접근하지 않고 유틸리티 함수로 자주 사용되는 메소드입니다. - 클래스 메소드(@classmethod)
클래스의 상태를 변경하거나 접근할 수 있는 메소드입니다.
클래스 자체를 첫 번째 매개변수로 받아들이며, 이 매개변수는 보통 cls라고 명명하여 사용합니다.
클래스 메소드는 클래스 변수를 읽거나 수정할 수 있고, 클래스 이름이나 인스턴스를 통해 호출할 수 있습니다.
밑의 예시를 통해 메소드 생성법과 호출법을 통해 차이를 더 쉽게 이해할 수 있습니다.
class Example:
class_variable = 'Class Variable'
def __init__(self, instance_variable):
self.instance_variable = instance_variable
@staticmethod
def static_method():
return 'Static Method: Cannot access instance or class variables'
@classmethod
def class_method(cls):
return f'Class Method: Can access {cls.class_variable}'
def instance_method(self):
return f'Instance Method: Can access {self.instance_variable} and {self.class_variable}'
example = Example('Instance Variable')
# 정적 메소드 호출
print(Example.static_method()) # Static Method: Cannot access instance or class variables
# 클래스 메소드 호출
print(Example.class_method()) # Class Method: Can access Class Variable
# 인스턴스 메소드 호출
print(example.instance_method()) # Instance Method: Can access Instance Variable and Class Variable
추가적으로 정적 메소드와 클래스 메소드의 차이를 표를 정리하여 어떤 차이가 있는지 더 쉽게 이해할 수 있습니다.
특성 | 정적 메소드 | 클래스 메소드 |
접근 가능한 데이터 | 클래스 상태나 인스턴스 상태에 접근하지 않음 | 클래스 변수에 접근 가능 |
첫 번째 매개변수 | 없음 | cls (클래스를 나타냄) |
사용 목적 | 유틸리티 함수, 독립적인 기능 제공 | 클래스 상태 변경 또는 접근 |
호출 방법 | 클래스 이름을 통해 호출 | 클래스 이름 또는 인스턴스를 통해 호출 |
정적 메소드가 유용한 상황
객체 지향 프로그래밍을 하면서 정적 메소드를 활용할 상황이 생기고, 이러한 상황에 정적 메소드를 활용할 경우 좋은 결과를 얻을 수 있습니다.
- 공통적으로 사용되는 유틸리티 함수들을 정의할 때
- 특정 객체에 종속되지 않는 기능을 제공할 때
- 인스턴스나 클래스가 필요하지는 않지만 직접적인 연관이 있어 묶어서 클래스 안에서 제공하는 것이 좋을 것 같을 때
- 클래스에 속하지만 인스턴스에 종속되지 않는 메소드, 클래스의 속성이나 다른 메소드에 접근할 필요가 없을 때
정적 메소드는 클래스 수준에서 동작하며, 메모리 사용을 절약하고, 프로그램 구조를 더 명확하게 만들 수 있습니다.
'스프린트 > 위클리페이퍼' 카테고리의 다른 글
[#6] 스프린트 DA 트랙 8주차 위클리 페이퍼(차원 축소, 고유값과 고유벡터, 히스토그램의 단점과 그 대안) (0) | 2024.08.08 |
---|---|
[#5] 스프린트 DA 트랙 5주차 위클리 페이퍼(절대 경로와 상대 경로, Git, Branch) (0) | 2024.07.17 |
[#3] 스프린트 DA 트랙 3주차 위클리 페이퍼(데이터 전처리, t-test) (0) | 2024.07.03 |
[#2] 스프린트 DA 트랙 2주차 위클리 페이퍼(제 1종 오류와 제 2종 오류, p값) (0) | 2024.06.27 |
[#1] 스프린트 DA 트랙 1주차 위클리 페이퍼(사분위수, 기술통계 및 추론통계) (0) | 2024.06.20 |
데이터 분석을 공부하고 카페를 열심히 돌아다니는 이야기
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!