Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

Nonamed Develog

[TIL][240722] 파이썬 문법 빈틈을 메꾸자 (5) 본문

WHAT I LEARN/TIL

[TIL][240722] 파이썬 문법 빈틈을 메꾸자 (5)

노네임드개발자 2024. 7. 22. 21:21

 

새로 알게 된 점은 무엇인가?

절차 지향 프로그래밍 vs 객체 지향 프로그래밍

- 절차 지향 프로그래밍

  • 프로그램을 여러 순서대로 진행되는 절차(함수나 명령)들로 구성된다.
  • 기능 중심이고 순서가 존재하기 때문에 빠른 속도를 가지고 있다.
  • 하지만 프로그램이 커지고 데이터가 많아질수록 너무 복잡해질 수 있다.

- 객체 지향 프로그래밍

  • 절차 지향 프로그래밍으로는 생산성이 낮아지므로 데이터 중심으로 프로그래밍 개편
  • 하나의 프로그램을 여러 개의 독립된 객체들과 상호작용
  • 현실 세계를 프로그램 설계에 반영(추상화)
  • 설계 시 정밀하게 다양한 객체 간 상호 작용 구조를 만들어야 하기 때문에 시간이 필요하다.
  • 실행속도가 절차 지향 보다 상대적으로 느리긴 하지만 처리구조가 비슷해 빠른 편이라고 할 수 있다.

클래스와 객체

  • 속성(data, 변수)과 행동(method, 함수)으로 규정된 모든 것! 객체(Object = 속성(Attribute) + 기능(Method)
  • 클래스를 만는 것은 사용자 정의 타입을 만드는 것과 같다. 
    • 타입{type): 연산자(operator)와 조작(method)
    • 속성(attribute): 상태(data)
    • 조작(method): 행위(함수)
  • 객체란 클래스에서 정의한 것을 토대로 메모리(실제 저장 공간)에 할당된 것이다.
  • 프로그램에서 사용되는 데이터 또는 식별자에 의해 참조되는 공간을 의미하고 변수, 자료구조, 함수 메서드 등이 될 수 있다.
  • 파이썬의 모든 것이 객체다...!
[3, 2, 1].sort()
# 리스트.정렬
# 객체.행동
  • 하나의 객체는 특정 타입(class)의 인스턴스이다.

클래스 기본 문법

  1. 클래스 정의, class MyClass
    클래스를 정의하고 밑에 자세한 내용을 적을 수 있다.
  2. 인스턴스 생성, my_instance = MyClass()
    MyClass 클래스 생성자 호출하여 Myclass 객체를 return 한다. my_intance는 Myclass의 인스턴스이다.
  3. 메서드 호출, my_instance.my_method()
    my_instance가 지니고 있는 method()를 호출한다. mothod() 내부의 self는 my_instance를 가리킨다.
  4. 속성 접근, my_instance.my_attribute
    속성이란 클래스에서 정의되는 변수로 각 객체의 고윳값을 나타낸다.

클래스와 인스턴스

클래스는 다른 말로 타입이라고도 하며 일종의 틀로서 클래스를 통해 객체를 생성할 수 있다.

class Person:
    pass

print(type(Person))  # class는 class type이다(?)

person1 = Person() # 인스턴스 p1

print(isinstance(person1, Person))  #isinstance(인스턴스, 확인할 클래스/데이터)
print(type(person1))  # Person의 인스턴스

# <class 'type'>
# True
# <class '__main__.Person'>

 

객체 비교하기

  • == : 동등한, 내용이 같은 경우 True
  • is : 동일한, 동일한 객체를 가리키는 경우(주소까지)
    • 거의 쓸 일이 없지만 None, True, False 등 주소가 고정되어 있는 것은 is를 사용해도 무방하다.

속성과 이름 공간(namespace)

  • 특정 데이터 타입, 클래스 객체가 가지게 될 상태, 데이터를 의미하며 클래스 변수, 인스턴스 변수가 존재한다.
class Person:
    name = 'harry'  # 클래스 변수
    age = 35  # 클래스 변수

    def __init__(self, name):
        self.name = name  # 인스턴스 변수

person1 = Person('철수')
print(person1.name)  # 철수
  • self.name에서 .은 왼쪽에 있는 객체가 소유하고 있는 어떤 값을 가져온다는 의미이다. 따라서 self라는 객체가 가지고 있는 name이라는 속성에 함수의 인수로 들어온 name을 대입한다. 변수를 정의할 때 대입문을 통해 정의하는 것과 비슷하다.
  • 클래스를 정의하면 클래스와 해당하는 이름 공간(namespace)이 생성되고 인스턴스를 만들면 인스턴스 객체가 생성되고 또 다른 이름 공간이 생성된다.
  • 인스턴스에서 특정 속성에 접근하려면 인스턴스-클래스 순으로 탐색할 수 있다.(반대는 안된다) LEGB 룰과 비슷.

클래스 변수: 클래스 변수로 변경할 때는 클래스 변수만 사용한다.

class Person:
    count = 0  # 클래스 변수

    def __init__(self, name):
        self.name = name
        Person.count += 1  # 인스턴스가 생성될 때마다 클래스 변수 1씩 증가

person1 = Person('사람1')
person2 = Person('사람2')  # 2번

print(Person.count)  # 2

 

인스턴스 메서드

  • 호출 시 첫번째 인자로 인스턴스 자신(self)이 자동으로 전달된다.
  • 인스턴스 자기 자신(self) ➡️ 인스턴스의 namespace에 접근 가능하다.(self는 넘겨주지 않아도 상관없다)
  • 인스턴스 변수를 사용하거나 인스턴스 변수에 값을 설정하는 메서드다.
  • 클래스 내부에 정의되는 메서드의 기본이다.
my_instance.intance_method(a)  # self는 자동 배정

 

매직 메서드: 특정 상황에 자동으로 호출되는 메서드

  • 특수한 동작을 위해 만들어진 메서드로 __init__(self)과  __str__(self)가 많이 쓰인다.

생성자 메서드 __init__(self)

  • 생성자라는 특별 메서드이다. 객체가 생성될 때 객체가 사용할 속성(attribute) 초기값 설정하는 역할을 한다.
  • 클래스를 이용하여 인스턴스 객체가 생성할 때 자동으로 호출된다.
# 클래스를 호출할 때 괄호를 쓰는 이유
Person() = Person.__init__(self)
  • 속성 초기화: .을 기준으로 왼쪽에 있는 객체가 소유하고 있는 속성을 가져온다는 의미
self.run = run
# self라는 객체가 가지고 있는 run이라는 속성에 함수의 인수로 들어온 run을 대입하겠다는 뜻
# 두 run은 서로 다르다
class Person:
    def __init__(self, name, *args, **kwargs):
        print("__init__")
        self.name = name
        if "age" in kwargs.keys():
            self.age = kwargs["age"]
        else:
            self.age = 0


p1 = Person("aiden", age=22)
print(p1.name) 
print(p1.age)

# __init__
# aiden
# 22

p2 = Person("jun")
print(p2.name)
print(p2.age)

# __init__
# jun
# 0

 

 

클래스 메서드: 클래스가 사용할 메서드

@classmethod  # 데코레이터를 사용하여 정리
  • 호출 시 첫 번 쨰 인자로 클래스(cls)가 전달된다.
class Person:
    def __init__(self, name):
        self.name = name

    @classmethod
    def hello(cls):
        print("Hello")

    def run(self):
        print("싫어 !")


Person.hello()  # Hello

 

데코레이터: 파이썬의 핵심 기능 중 하나

  • 함수를 어떤 함수로 꾸며서 새로운 기능을 부여한다.
  • 기존 함수를 입력받아서 원하는 기능을 추가한 함수로 return 할 수 있다.
  • @함수명 형태로 함수 위에 작성
  • 순서대로 적용되기 때문에 작성 순서가 중요하다.
def deco(func):
    def wrapper():
        func()
        print("^~^")

    return wrapper


@deco
def hello():
    print("hello")
    

hello()
# 응용하면 이렇게 쓸 수도 있다.
def deco(func):
    def wrapper(*args, **kwargs):
        func(*args, **kwargs)
        print("^~^")

    return wrapper

 

클래스 메서드와 인스턴스 메서스

  • 클래스 메서드는 클래스 변수만 사용 가능하다.
  • 인스턴스 메서드는 클래스 변수, 인스턴스 변수 둘 다 사용 가능하다.

 

스태틱 메서드

  • 인스턴스 변수, 클래스 변수를 전혀 다루지 않는 메서드이다. 속성을 다루지 않고 단지 기능(행동)만 하는 메서드를 정의할 때 사용한다.
  • 객체 상태나 클래스 상태를 수정할 수 없다.
  • @staticmethod 데코레이터를 사용하여 정의할 수 있다.
  • 클래스 namespace에 귀속되어 해당 클래스에 한정하여 일반 함수의 기능을 한다.

무엇을 느꼈고 내일은 무엇을 할까?

객체 지향 프로그래밍에 대해서 공부하면서 느낀 것은 개발자들은 귀찮은 것을 참 싫어한다는 것이다. 그들의 귀찮음이 작업의 편의성을 올렸지만 배우는 입장에선 여간 짜증 나는 일이 아닐 수 없다... 오늘 배운 것을 바탕으로 스택, 큐를 구형해 봐야겠다.