1. 클래스와 객체
클래스는 객체를 만들기 위한 청사진이라고 할 수 있으며
속성과 메서드로 구성이 된다
이때 속성 (Atrribute) 은 클래스에 정의된 변수로, 데이터를 정의하며
메서드 (method)는 객체의 동작을 정의한다
객체는 클래스의 인스턴스로, 클래스라는 설계도로부터 실제로 생성된 구체적인 데이터와 기능을 가지는 실체이다.
객체는 클래스에 정의된 속성과 메서드를 가지고 있다
캡슐화 : 객체의 속성과 메서드를 하나로 묶고, 일부를 외부에 감추어 객체 내부의 구현을 숨기는 원칙, 이를 통해 데이터의 무결성을 보호하고, 외부에서의 직접 접근을 제한함
상속 : 기존 클래스를 기반으로 새로운 클래스를 만드는 방법, 상속을 통해 부모 클래스의 속성과 메서드를 자식 클래스가 물려받아 사용할 수 있으며, 이를 확장하거나 수정할 수 있음
다형성 : 동일한 이름의 메서드가 여러 객체에 따라 다르게 동작할 수 있는 원칙
추상화 : 복잡한 시스템을 단순화하여, 필요한 부분만 보여주고 나머지는 감추는 원칙임, 추상화를 통해 사용자는 객체 내부 구현에 신경 쓰지 않고, 필요한 인터페이스만 사용할 수 있음
ex1)
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod # 반드시 speak메서드를 구현하도록 함
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "멍멍"
ex2)
PyTorch에서의 클래스 사용 : nn.Module 클래스를 상속받아 신경망을 정의하고, 이를 통해 딥러닝 모델을 구성함
# 클래스 생성 규칙
class ai_student:
# 속성 초기화
def __init__(self, input_name):
self.name = input_name
# 메서드
def greet(self):
print(f"{self.name} 님 안녕하세여")
def test():
print("출력이 될까?!) # 출력 되지 않음 -> test메서드의 인자로 self를 넣어줘야 함
# 객체를 사용 -> 인스턴스로
alice = ai_student("ALICE")
alice.name # ALICE
alice.greet()
alice.test()
alice.age = 22
alice.age # 22 추가되었음을 알 수 있음
매직메서드
__repr__
객체의 "공식적인" 문자열 표현을 반환하는 메서드로, 주로 디버깅을 위해 사용된다
__add__
객체 간의 덧셈 연산을 정의하는 메서드로, + 연산자를 재정의할 수 있다
__eq__
두 객체가 같은지 비교하는 메서드로, == 연산자를 재정의한다
__str__
객체의 "공식적인" 문자열 표현을 반환하는 메서드로, 주로 디버깅을 위해 사용된다
class Ai_student:
def __init__(self, input_name, age):
self.name = input_name
self.age = age
def __repr__(self):
return f"Ai_student({self.name}, {self.age})"
def __add__(self, other):
print(self.age + other.age)
print(self.name + other.name)
def __eq__(self, other):
if self.name == other.name:
print("같은 이름입니다!")
else:
print("다른 이름입니다!")
def __str__(self):
return f"안녕하세요! 저는 {self.name}이고 나이는 {self.age} 살 입니다"
alice = Ai_student("alice", 22)
eric = Ai_student("eric", 22)
alice + eric # 44 / aliceeric
alice == eric # 다른이름입니다!
print(alice) # 안녕하세요! 저는 alice이고 나이는 22살 입니다!
클래스 변수
class myClass:
class_variable = 0
@classmethod
def increment(cls):
cls.class_variable += 1
myClass.increment() # 이때 class_variable의 값이 1씩 증가됨을 확인할 수 있음
정적 메서드
만약 클래스나 객체와는 관련이 없지만 클래스의 맥락 상 의미가 있다면?
-> staticmethod 데코레이션을 이용하여 정의함
class Utility:
@staticmethod
def add(x, y):
return x + y
result = Utility.add(3, 5)
print(result) # 8
상속
장점
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "소리를 냅니다"
def test(self):
print("테스트입니다")
class Dog(Animal):
def __init__(self, name, age):
super().__init__(name) # name 초기화 하는 것을 상속받음
self.age = age
def speak(self):
return f"{self.name}가 멍멍 짖습니다!"
dog = Dog("Buddy", 22)
print(dog.speak()) # Buddy가 멍멍 짖습니다!
만약 자식 클래스에게 특정 메서드를 강제하고 싶다면?
-> 추상 메서드를 이용할 것
@abstractmethod
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Dog(Animal):
def __init__(self, name):
self.name = name
# 반드시 작성해야 하는 메서드이다
def sound(self):
print("이름 멍멍")
a = Dog("bbb")
a.sount() # 이름 멍멍
파일 읽기 open(파일, "r")
read() 메서드
readline() 메서드
readlines() 메서드
파일 쓰기 open(파일, "w")
lines_raw = "첫번째 줄 \n 두번째줄 \n 세번째 줄"
lines = ["첫번째 줄", "두번째 줄", "세번째 줄"]
f = open("없는파일.txt", "w")
f.writelines(lines) # 리스트에 담긴 여러 개를 한꺼번에 씀 -> 같은 줄로
f.write(lines_raw) # 문자열 내부에서 줄바꿈 처리를 했기 때문에 띄어쓰기 되어서 써짐
파일 쓰기 - 추가 모드 open(파일, "a")
기존의 파일의 내용을 유지하고, 파일 끝에 데이터를 추가할 때 사용
with open("output.txt", "a") as file:
file.write("이내용은 기존 파일의 끝에 추가됨")
파일 닫기 - 파일.close()
반복 가능한 객체 (iterable)
이터레이터 (iterator)는 반복 가능한 객체의 요소를 하나씩 꺼내오는 객체이다.
이터레이너틑 iter()메서드와 next() 메서드를 구현해야 하며,
next() 메서드를 호출할 때마다 다음 요소를 반환함
더이상 꺼낼 요소가 없으면 StepIteration 예외를 발생시킴
제너레이터
def simple_generator():
yield 1
yield 2
yield 3
gen = simple_generator()
print(next(gen)) # 1
print(next(gen)) # 2
print(next(gen)) # 3
ex-1.
yield 값만 print()함 , 즉, 바뀌는 a값만 print() 함
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for num in fibonacci(10):
print(num)
ex-2.
제너레이터 표현식이 실제로 쓰인 예시
gen_exp = [x * x for x in range(5)]
for num in gen_exp:
print(num)
데코레이터
데코레이터란 메서드를 변경하지 않고, 추가적인 기능을 쉽게 추가할 수 있는 방법임. 이 데이터는 함수를 다른 함수로 감싸서, 원래 함수에 새로운 기능을 덧붙일 때 사용함
컨텍스트 매니저
ex. with()를 실행함으로 자동으로 file 안에 write를 수행하고 파일을 닫아줌
with open("열_파일.txt", "w") as file:
file.write("써야지")
2. 프레임워크
라이브러리
란 특정 기능을 수행하는 모듈이나 함수들의 집합으로, 개발자가 필요에 따라 호출하여 사용할 수 있다. 라이브러리를 사용하는 개발자는 주도권을 가지고, 필요한 기능을 선택적으로 호출하여 코드에 통합한다.
ex.
import math
result = math.sqrt(16)
print(result) # 4.0
프레임워크
애플리케이션의 구조와 흐름을 제공하는 툴로, 일정한 방식에 따라 코드를 작성하도록 함
프레임워크는 개발자가 정의한 코드와 미리 제공된 코드를 결합해 동작하며, 일반적으로 프레임워크가 전체 흐름을 제어함
장고
구성요소
모델 : 데이터베이스 구조를 정의하고, 데이터의 상호작용하는 역할을 함
뷰 : 사용자가 보는 화면을 담당하며, 모델에서 가져온 데이터를 사용해 탬플릿에 전달함
템플릿 : HTML을 생성하는 역할을 하며, 뷰에서 전달받은 데이터를 표시함
URL conf (컨퍼그): URL과 뷰를 연결하는 역할을 하며, 사용자가 특정 URL로 접근할 때 어떤 뷰를 호출할 지를 결정함
폼 (form) : 사용자의 입력을 받고, 이를 처리하여 유효성 섬사를 수행하는 방법을 적음
Admin Interface : 장고가 제공하는 관리자 인터페이스를 사용해 데이터를 관리하고, 커스터마이즈하는 방법을 익힐 수 있음
동작 흐름 (MVT흐름)
1. URL 요청 : 사용자가 웹 브라우저에서 특정 URL을 요청함
2-1. view 호출 : URL conf가 요청한 URL에 맞는 view를 호출함
2-2. 데이터 처리 및 템플릿 렌더링 : view는 필요한 데이터를 모델에서 가져오고, 템플릿에 전달하여 HTML을 생성함
3. HTML 응답: 생성된 HTML을 웹 브라우저에 반환하여 사용자에게 표시함
예를 들어보자
1. 회원 등록 버튼을 클릭함
2-1. 회원이 적은 회원 등록 내용을 서버로 전달함
2-2. 회원 등록 성공이 되었을 때 회원정보는 서버의 DB에 적혀야 하며 등록된 회원 아이디를 응답 HTML에 전달해야 함
3. 회원 등록 성공 HTML에 등록된 회원 아이디를 포함해 사용자에게 표시함