본문 바로가기
코딩/파이썬

파이썬 - 객체지향과 클래스

by Song1234 2024. 3. 18.

1. 객체지향 프로그래밍

객체지향 프로그래밍(Object-Oriented Programming, OOP)은 소프트웨어를 설계하고 구현하는 데 사용되는 중요한 프로그래밍 패러다임 중 하나입니다. 이 패러다임은 프로그램을 "객체"라고 불리는 독립적인 개체로 나누고, 이러한 객체들 간의 상호작용을 통해 프로그램을 구성하는 개발 방법론입니다.

※절차지향 프로그래밍

절차지향프로그래밍은 프로그램을 작성할 때 일련의 절차 또는 단계에 따라 코드를 구성하는 방식입니다. 이러한 단계나 절차들은 주로 함수나 서브루틴으로 나누어져 있으며, 각각의 함수는 특정한 작업을 수행합니다. 주로 '입력 - 처리 - 출력'의 순차적인 절차를 따르며, 코드를 위에서부터 아래로 실행하면서 데이터를 처리하는 방식으로 동작합니다. C 언어와 같은 프로그래밍 언어는 주로 절차지향적인 스타일을 따릅니다.

※함수형 프로그래밍

함수형프로그래밍은 함수(function)를 최우선 으로 취급하여 프로그램을 작성하는 패러다임입니다. 함수는 다른 함수에 전달되거나 반환될 수 있으며, 함수들 간의 조합을 통해 복잡한 작업을 수행합니다. 상태를 변경하지 않고 데이터를 처리하고, 부작용(side effect)을 최소화하려는 노력이 있습니다. 함수형 언어로는 Haskell, Lisp, Clojure 등이 있으며, 몇몇 다른 언어들도 함수형 프로그래밍을 지원합니다. 함수형 프로그래밍은 병렬처리와 상태 관리에 용이하며, 함수들을 조합하여 간결하고 안정적인 코드를 작성하는데 도움이 됩니다.

프로그래밍 방식은 언어에따라 나눠지는것이아닌 코드를 작성하는 방식에따라 위에틀로 나눌수있다.

※객체 는 명사와 동사를 가지고 있는 묶음 이라고 할수있다.

  • 특정개체를 표현하기위한 명사
    ex) 사람의 이름, 혈액형, 키, 몸무게, 생김새 등의 명사(변수의 형태와 유사함)
  • 특정개체를 표현하기위한 동사
    ex) 먹는다, 걷는다, 잔다 등의 동사 (함수의 형태와 유사함)

2. 클래스

  • 객체(Object): 객체는 현실 세계에서의 실제 개체나 추상적인 개념을 모델링한 것입니다. 예를 들어, 자동차, 사람, 은행 계좌 등이 객체가 될 수 있습니다. 객체는 데이터(속성, 상태)메서드(동작, 함수)로 구성됩니다.
  • 클래스(Class): 클래스는 객체를 만들기 위한 템플릿 또는 설계도입니다. 클래스는 객체의 공통 속성과 동작을 정의하며, 객체를 생성하는데 사용됩니다. 예를 들어, "자동차" 클래스는 모든 자동차 객체가 가져야 하는 속성(색상, 속도)과 메서드(주행, 멈춤)를 정의할 수 있습니다.
  • 인스턴스(Instance): 클래스를 기반으로 실제로 생성된 객체를 인스턴스라고 합니다. 클래스는 여러 인스턴스를 생성할 수 있으며, 각 인스턴스는 독립적인 데이터와 메서드를 가집니다.
    변수가 가리키고 있는 클래스가 복제된형태 를 인스턴스 라고 한다

객체를 생성하면 클래스의 모양대로 메모리에 저장된다.


2-1. 클래스 만들기

class 클래스이름:
    # 클래스 속성(멤버 변수) 정의
    속성1 = 초기값1
    속성2 = 초기값2

    # 생성자 메서드 (생략 가능)
    def __init__(self, 매개변수1, 매개변수2, ...):
        # 인스턴스 속성 초기화
        self.속성1 = 매개변수1
        self.속성2 = 매개변수2
        #self.을 붙여주어야 클래스내에 함수에서 사용할수있다

    # 메서드(멤버 함수) 정의
    def 메서드1(self, 매개변수1, 매개변수2, ...):
        # 메서드 동작 정의
        pass

    def 메서드2(self, 매개변수1, 매개변수2, ...):
        # 메서드 동작 정의
        pass

2-1. 객체(인스턴스) 생성

class Dog:# 클래스 생성
    pass
# 객체생성
Rucy = Dog()
print(Rucy)
print(type(Rucy))

결과:
<main.Dog object at 0x7d2141983640>
<class 'main.Dog'>

PPomi = Dog()
print(PPomi)
print(type(PPomi))

결과:
<main.Dog object at 0x7d2141983190>
<class 'main.Dog'>

클래스의 모양대로 메모리에 올라가고 각각의 다른객체가 만들어진다.


2-2. 객체 속성 초기화

class Dog:
    name = ''
    age = 0
    family = ''
Rucy = Dog() 
print(Rucy.name) 
print(Rucy.age)
print(Rucy.family)

결과:

0

객체안 멤버들에 접근을 할땐 . 을 사용한다.

Rucy.name = '루시'
Rucy.age = 14
Rucy.family = '포메'
print(Rucy.name)
print(Rucy.age)
print(Rucy.family)

결과:
루시
14
포메

PPomi = Dog()
PPomi.name = '뽀미'
PPomi.age = 7
PPomi.family = '폼피츠'
print(PPomi.name)
print(PPomi.age)
print(PPomi.family)

결과:
뽀미
7
폼피츠

print(PPomi)
print(Rucy)

결과:
<main.Dog object at 0x7d21292a81f0>
<main.Dog object at 0x7d21292aac20>

형태는 같지만 각각다른 객체이므로 주소값이 다르다.


2-3. 메서드의 사용

class Dog:
    name = ''
    age = 0
    family = ''

    def eat(self): # 메서드 생성
        print('사료를 먹습니다!')

메서드에는 항상 self 를 입력 해 줘야한다.
함수는 객체를 생성할때마다 생성되는게 아닌 메모리에 하나만 저장되고 여러 인스턴스에서 공유해서 사용이된다.
self는 호출한 출처를 알기위해 주소값을 받는 매개변수이다.

Rucy = Dog()
Rucy.eat()

결과:
사료를 먹습니다!

PPomi = Dog()
PPomi.eat()

결과:
사료를 먹습니다!

class Dog:
    name = ''
    age = 0
    family = ''

    def eat(): 
        print('사료를 먹습니다!')
Rucy = Dog()
Rucy.eat()

결과:
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-21-273686394847> in <cell line: 2>()
      1 Rucy = Dog()
----> 2 Rucy.eat()

TypeError: Dog.eat() takes 0 positional arguments but 1 was given

매개변수를 지정하지 않았는데 호출한 변수에서 주소값이 전달되어 오류가 뜨게된다.
이때 메서드에 self 를 추가하면 해결된다.


3. 생성자

파이썬에서 생성자(Constructor)는 클래스의 인스턴스가 생성될 때 자동으로 호출되는 특별한 메서드입니다. 생성자는 객체의 초기화를 담당하며, 객체가 생성될 때 필요한 속성을 초기화하고 설정하는 역할을 합니다. 파이썬에서 생성자 메서드는 init라고 이름이 정해져 있습니다.

class 클래스이름:
    def __init__(self, 매개변수1, 매개변수2):
        self.속성1 = 매개변수1
        self.속성2 = 매개변수2

class Dog:
    def __init__(self):
        print(self, 'init 호출!')
Rucy = Dog()

결과:
<main.Dog object at 0x7d21292ab8b0> init 호출!

class Dog:
    def __init__(self):
        self.name = ''
        self.age = 0

init 안에서는 self 가 없으면 함수 내에서는 사용할수 있지만,

외부에서 호출을하면 위치를 찾을수 없기때문에 접근을 할수없어 에러가난다.

Rucy = Dog()
print(Rucy)
print(Rucy.name)
print(Rucy.age)

결과:
<main.Dog object at 0x7d21292a9390>

0

class Dog:
    def __init__(self, name, age, family = '없음'):
        self.name = name
        self.age = age
        self.family = family
Rucy = Dog('루시', 14, '포메')
print(Rucy.name)
print(Rucy.age)
print(Rucy.family)

결과:
루시
14
포메

PPomi = Dog('뽀미', 7)
print(PPomi.name)
print(PPomi.age)
print(PPomi.family)

결과:
뽀미
7
없음

생성자를 통해서 객체를 생성할때 값을 준 상태에서 만들수 객체를생성 할 수 있다.


4. 메서드

메서드(Method)는 객체지향 프로그래밍(OOP)에서 사용되는 함수와 비슷한 개념이지만, 클래스 내부에 정의되어 특정 객체에 연결된 함수입니다. 메서드는 해당 클래스의 모든 객체에서 공유되며, 객체의 동작을 정의하거나 특정 작업을 수행하는 데 사용됩니다.

4-1. 메서드 정의

class Counter:
    # 생성자
    def __init__(self):
        self.num = 0
    # 메서드
    def increment(self):
        self.num += 1

    def current_value(self):
        return self.num

    def decrement(self):
        self.num -= 1

    def reset(self):
        self.num = 0
KBbank = Counter()
print(KBbank.num) 
print(KBbank.current_value())
KBbank.increment()
KBbank.increment()
KBbank.increment()
print(KBbank.current_value())
KBbank.decrement()
print(KBbank.current_value())

결과:
0
0
3
2

값을 직접 접근해서 변경하는것 보다 메서드를 이용해서 변경하는것이 안전하다.

Hanabank = Counter()
print(Hanabank.current_value())
Hanabank.increment()
Hanabank.increment()
Hanabank.increment()
Hanabank.increment()
Hanabank.increment()
print(Hanabank.current_value())

결과:
0
5

Hanabank.reset()
print(Hanabank.current_value())

결과:
0


4-2. 메서드 타입

  • 인스턴스 메서드(Instance Method): 객체의 상태를 조작하거나 객체에 특정 작업을 수행하는 메서드입니다. 대부분의 클래스 메서드는 인스턴스 메서드입니다. 위의 예제에서 보여진 init 메서드도 인스턴스 메서드입니다.
  • 클래스 메서드(Class Method): 클래스 레벨에서 동작하며, 모든 인스턴스가 공유하는 메서드입니다. 클래스 메서드는 @classmethod 데코레이터를 사용하여 정의하며, 첫 번째 매개변수로 cls를 사용합니다.
  • 정적 메서드(Static Method): 특정 클래스나 인스턴스와 관련이 없는 메서드로, 클래스 내부에 정의되어 있지만 클래스나 인스턴스와 독립적으로 호출될 수 있습니다. 정적 메서드는 @staticmethod 데코레이터를 사용하여 정의합니다.
class Math:
    def add(self, x, y):
        return x + y
    def multiply(self, x, y):
        return x * y
math = Math() # 객체 생성

result1 = math.add(10, 3)
print(result1)

result2 = math.multiply(10, 3)
print(result2)

결과:
13
30


클래스 메서드 사용

class Math:
    str1 = 'Hello! '
    @classmethod # classmethod를 선언하고 밑에 함수를 선언하면 함수가 메소드의 기능을 내려받게 된다.
    def add(cls, x, y):
        return x + y

    @classmethod
    def multiply(cls, x, y):
        return x * y

    @classmethod
    def hello(cls, name):
        return cls.str1 + name 
  • cls는 class의 약자 cls를 입력하면 해당 함수가 저장되어 있는 클래스의 주소값을 받는다.

  • cls.변수명 을 입력하면 해당 클래스 안에 변수를 찾아 사용할수 있다.

    print(Math.add(10, 3))
    print(Math.multiply(10, 3))
    print(Math.hello('김사과'))

    결과:
    13
    30
    Hello! 김사과

객채를 선언하지 않아도 클래스 이름으로 바로 접근해서 사용할 수 있다.


정적 메서드 사용

class Math:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def add(self):
        return self.x + self.y
    def multiply(self):
        return self.x * self.y
    @staticmethod 
    def subtract(x, y): 
        return x * y

클래스를 선언할 때 메모리에 먼저 올라가고 다른 메서드 들과 객체를 공유할 수 없다.(slef사용불가)
클래스 내에 다른 메서드들과 관련이 없고 독립적인 메서드가 필요할때 사용

'코딩 > 파이썬' 카테고리의 다른 글

파이썬 상속  (0) 2024.03.19
클로저와 데코레이터  (1) 2024.03.19
파이썬 - 콜백함수와 람다함수  (1) 2024.03.18
파이썬 - 변수의 범위  (0) 2024.03.18
파이썬 - 사용자 정의 함수  (0) 2024.03.15