학습일지

[스나이퍼팩토리] 한컴AI아카데미(26.04.27)

cd-record 2026. 4. 28. 09:09
추상 클래스

 

1. OOP(Object-Oriented Programming, 객체 지향 프로그래밍)

프로그래밍을 단순히 '데이터의 처리 과정'으로 보지 않고, 독립적인 '객체(Object)'들의 상호작용으로 구성하는 설계 철학'

  • 객체 지향의 4대 핵심 개념
    • 캡슐화 (Encapsulation): 객체의 내부 데이터와 메서드를 하나로 묶고, 외부에서 함부로 접근하지 못하도록 보호(정보 은닉)하는 것입니다. (예: 자동차의 복잡한 엔진 내부를 뜯어보지 않아도 운전대만으로 조작 가능)
    • 상속 (Inheritance): 부모 클래스의 기능을 자식 클래스가 그대로 물려받아 사용하는 것입니다. 중복 코드를 줄이고 기능 확장이 쉬워집니다.
    • 다형성 (Polymorphism): 같은 이름의 메서드라도 객체마다 다르게 동작하는 능력입니다. (예: '말하기'라는 명령을 내렸을 때, 사람은 '안녕', 개는 '멍멍'이라고 말하는 것)
    • 추상화 (Abstraction): 복잡한 내부 구현은 숨기고, 핵심적인 기능만 인터페이스로 노출하는 것입니다.

2. 추상 클래스 정의하기

파이썬에서 추상 클래스를 만들려면 내장 모듈인 abc에서 ABC 클래스와 @abstractmethod 데코레이터를 가져와야 합니다.

  • ABC: 추상 클래스를 만들기 위한 부모 클래스
  • @abstractmethod: 자식 클래스가 반드시 오버라이딩(재정의)해야 하는 메서드
from abc import ABC, abstractmethod

class Animal(ABC): # ABC를 상속받아 추상 클래스 설정
    @abstractmethod
    def speak(self):
        # 본문은 보통 비워두거나 pass를 사용합니다.
        pass

3. 인스턴스 생성 불가

추상 클래스는 미완성된 설계도이므로, 이를 직접 호출하여 객체(인스턴스)를 만들 수 없습니다. 시도할 경우 TypeError가 발생합니다.

# 에러 발생!
# my_animal = Animal() 

3. 메서드 구현 강제

추상 클래스를 상속받은 자식 클래스는 부모의 모든 추상 메서드를 구현해야만 객체를 생성할 수 있습니다.

class Dog(Animal):
    def speak(self):
        return "멍멍!"

class Cat(Animal):
    def speak(self):
        return "야옹~"

dog = Dog()
print(dog.speak()) # 출력: 멍멍!

참고: 만약 Cat 클래스에서 speak 메서드를 정의하지 않는다면, Cat 역시 인스턴스를 만들 수 없는 상태가 됩니다.


4. 추상 클래스를 사용하는 이유

추상 클래스는 협업이나 대규모 프로젝트에서 인터페이스 통일을 위해 사용합니다.

  • 규격화: 여러 개발자가 참여할 때, "동물 클래스를 상속받으면 무조건 speak 메서드는 만들어야 한다"는 규칙을 코드 수준에서 강제합니다.
  • 유지보수: 부모 클래스 타입으로 여러 자식 객체를 다룰 수 있어 코드가 유연해집니다 (다형성).

요약 코드 예시

from abc import ABC, abstractmethod

# 1. 추상 클래스 (설계도)
class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

# 2. 자식 클래스 (구체적인 구현)
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
        
    def area(self):
        return 3.14 * self.radius ** 2

class Square(Shape):
    def __init__(self, side):
        self.side = side
        
    def area(self):
        return self.side * self.side

# 사용 예시
shapes = [Circle(5), Square(4)]
for s in shapes:
    print(f"넓이: {s.area()}")

OOP.ipynb
0.01MB

 

 

 

lambda

 

1. 람다 함수의 기본 문법

일반적인 함수 정의 방식인 def와 달리, lambda 키워드를 사용합니다.

# 기본 형태
# lambda 인자 : 표현식

# 예시: 두 수를 더하는 함수
add = lambda x, y: x + y
print(add(5, 3))  # 출력: 8
  • 인자: 함수에 전달할 매개변수들 (여러 개 가능)
  • 표현식: 인자를 받아 계산할 식 (결과가 자동으로 반환됨)

2. 일반 함수(def) vs 람다 함수

두 방식의 차이를 비교해 보면 람다의 간결함을 알 수 있습니다.

구분 일반 함수 (def) 람다 함수 (lambda)
이름 함수명이 반드시 존재 이름이 없음 (익명)
길이 여러 줄의 로직 가능 오직 한 줄(표현식)만 가능
반환 return 키워드 사용 return 없이 결과값 자동 반환

3. 실무에서 람다가 활용되는 경우

람다는 보통 함수를 인자로 받는 고차 함수(map, filter, sorted 등)와 결합할 때 빛을 발합니다.

 

① 리스트 정렬 시 (sorted)

데이터의 특정 기준(Key)을 정하고 싶을 때 람다를 사용합니다

# (이름, 점수) 튜플 리스트
students = [("A", 80), ("B", 95), ("C", 70)]

# 점수(x[1])를 기준으로 정렬
sorted_students = sorted(students, key=lambda x: x[1]) #정렬할 값을 x[1]로 쓰겠다는 의미
print(sorted_students)  # 출력: [('C', 70), ('A', 80), ('B', 95)]

 

② 데이터 변환 (map)

리스트의 모든 요소에 동일한 규칙을 적용할 때 유용합니다.

nums = [1, 2, 3, 4, 5]
# 모든 요소에 10을 더함
plus_ten = list(map(lambda x: x + 10, nums))
print(plus_ten)  # 출력: [11, 12, 13, 14, 15]

 

③ 조건부 필터링 (filter)

조건에 맞는 데이터만 걸러낼 때 사용합니다.

nums = [1, 2, 3, 4, 5, 6]
# 짝수만 추출
evens = list(filter(lambda x: x % 2 == 0, nums))
print(evens)  # 출력: [2, 4, 6]

4. 람다 함수 사용 시 주의사항

  1. 가독성: 로직이 조금이라도 복잡해지면(예: 중첩 조건문 등) 람다보다는 일반 함수(def)를 쓰는 것이 코드 읽기에 훨씬 좋습니다.
  2. 재사용성: 한 번만 쓰고 버릴 로직에는 람다가 좋지만, 여러 곳에서 반복해서 사용한다면 이름을 가진 함수로 정의하는 것이 유지보수에 유리합니다.

lambda.ipynb
0.01MB

 

 

 

Flask

 

1. Flask란: Python 언어로 웹 애플리케이션을 만들 수 있게 도와주는 아주 간단하고 가벼운 웹 프레임워크

  • HTML 페이지를 보여주고,
  • 데이터를 전송하고 받아들이며,
  • 사용자 요청에 응답하고,
  • 나아가 데이터베이스, 사용자 인증, API 개발 등 다양한 기능까지 확장할 수 있습니다.

 

2. Flask 설치 방법(가상 환경 생성 및 활성화 권장)

pip install Flask #터미널에서

 

3. Flask 기본 구조

  • 애플리케이션 객체 생성
    • 모든 Flask 프로젝트는 Flask 클래스의 인스턴스를 생성하는 것에서 시작
    • app 객체는 애플리케이션의 중심이 되며, 라우팅, 설정 관리, 요청 처리 등을 담당합니다. __name__은 Flask가 모듈이나 패키지의 경로를 찾는 데 사용
from flask import Flask
app = Flask(__name__)
  • 라우팅(Routing)
    • 사용자가 브라우저 주소창에 특정 경로를 입력했을 때, 어떤 함수가 실행될지 결정하는 과정
    • @app.route 데코레이터를 사용하여 URL 경로와 파이썬 함수를 1:1로 매핑
@app.route('/')
def index():
    return "메인 페이지입니다."
  • 애플리케이션 실행
    • if __name__ == '__main__': 블록을 사용하여, 이 파일을 직접 실행할 때만 서버가 켜지도록 설정
    • debug=True 옵션은 에러 발생 시 상세한 디버그 화면을 보여주기 때문에 개발할 때 매우 유용
if __name__ == '__main__':
    # 0.0.0.0은 외부 접속 허용, port는 원하는 번호로 지정 가능
    app.run(host='0.0.0.0', port=5000, debug=True)
  • 요청(Request) 처리 및 응답(Response)
    • request 객체는 클라이언트(보통 웹 브라우저)가 서버로 보낸 모든 정보가 담긴 바구니
    • Request 객체의 주요 속성
속성 설명 예시 상황
request.args URL 쿼리 파라미터 ?name=kim&age=20
request.form POST 방식으로 보낸 폼 데이터 로그인 입력창 데이터
request.json JSON 형식의 데이터 API 요청 시
request.method 요청 방식 (GET, POST 등) 요청의 종류 확인
request.files 업로드된 파일 정보 이미지/문서 업로드
request.headers HTTP 헤더 정보 브라우저 정보, 인증 토큰
from flask import Flask, request

app = Flask(__name__)

@app.route('/submit', methods=['GET', 'POST'])
def submit():
    # 1. GET 방식: URL의 ?key=value 형태 추출
    # 예: /submit?name=홍길동
    name = request.args.get('name', '이름없음')
    
    # 2. POST 방식: 폼(Form) 데이터 추출
    # 예: <input name="age">
    age = request.form.get('age', 0)
    
    # 3. 요청 방식 확인
    method = request.method
    
    return f"이름: {name}, 나이: {age}, 방식: {method}"

 

* HTTP 메서드(GET, POST, PUT, DELETE)

메서드 의미 CRUD 역할
GET 가져오기 Read 서버의 데이터를 단순히 조회할 때 사용
POST 생성하기 Create 서버에 새로운 데이터를 보낼 때 사용
PUT 수정하기 Update 기존 데이터를 새로운 데이터로 전체 교체할 때 사용
DELETE 삭제하기 Delete 특정 데이터를 삭제할 때 사용

 

  • 템플릿 (Templates) 과 정적 파일 (Static)
    • HTML 파일에 파이썬 데이터를 넣어서 사용자에게 보여줍니다.
    • render_template 함수를 사용하며,
    • {{ 변수명 }}: 파이썬에서 전달받은 변수의 값을 출력할 때 사용
    • {% 로직 %}: if문, for문 같은 제어문(로직)을 작성할 때 사용 (화면에 직접 출력되지 않음)
    • 코드 예시

- flask.py

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    # 파이썬 변수를 HTML로 전달
    user_name = "개발자님"
    return render_template('index.html', name=user_name)

if __name__ == '__main__':
    app.run(debug=True)

 

- templates/index.html

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <h1>안녕하세요, {{ name }}님!</h1>
    
    <img src="{{ url_for('static', filename='images/logo.png') }}" alt="로고">
</body>
</html>

 

- static/css/style.css

/* 스타일은 서버의 로직과 관계없이 고정되어 있음 */
h1 {
    color: blue;
    font-family: sans-serif;
}
구분 템플릿 (Templates) 스태틱 (Static)
파일 형식 .html .css, .js, .png, .jpg 등
변화 가능성 서버 데이터에 따라 변함(동적) 정해진 파일을 그대로 전달 (정적)
처리 방식 Jinja2 엔진이 렌더링 그대로 브라우저에 전송
주요 용도 웹 페이지 뼈대(구조) 스타일링, 애니메이션, 이미지

 

4. 동적 경로 변수 (Dynamic Routing) / 쿼리 스트링 방식(/search?q=Flask)

  • 동적 경로 변수: URL 경로의 일부분을 고정하지 않고, 사용자가 입력하는 값에 따라 유연하게 받아오는 기술
    • /  ( /user/홍길동 ): 리소스 경로를 정의, 매개변수 형태가 <isbn> 식일 때 리소스 경로에서는 값을 함수의 인자로 전달받아 처리함
    • 문자형 관련 변환기 정리
      변환기 설명 예시 URL
      <string> (기본값) /를 제외한 모든 문자열을 받습니다. /user/hong
      <path> /를 포함한 모든 경로를 문자열로 받습니다. (파일 경로 처리 시 유용) /files/dir/a.txt
      <int> (기본값) /를 제외한 모든 정수를 받습니다. /user/1
      <float> (기본값) /를 제외한 모든 실수을 받습니다. /user/11.0
      <any(...)> 지정된 목록 중 하나만 허용합니다. /color/red (blue, green도 가능)
from flask import Flask

app = Flask(__name__)

@app.route('/book/<isbn>')
def find_book(isbn):
	return f"{isbn} 책은 있습니다."

if __name__ == '__main__':
    app.run(debug=True, host = '0.0.0.0')
# [host]
# host='127.0.0.1' (기본값) - localhost
# host='0.0.0.0' - 모든 대역대 ip에서 접근
# host='10.0.66.200' - 특정 ip로 접근

 

  • 쿼리 스트링 방식: URL 뒤에 ?를 붙여서 추가 정보를 전달합니다. 주로 검색 조건이나 필터를 넘길 때 씁니다.
    • ? ( /search?q=Flask ) : 추가 정보를 전달, 매개변수 형태가 /search 처럼 없으면서 값을 q=Flask 형태로 넘길 때 쿼리 매개변수는 함수 내에서 request.args.get으로 값을 전달받아 처리함.
from flask import Flask, request
app = Flask(__name__)

@app.route('/search')
def search():
    query = request.args.get('q')  # get방식으로 넘어온 값 받아오기 (쿼리 스트링)
    return f'검색어: {query}'
    
if __name__ == "__main__":
	app.run(debug=True)

 

* 요약 정리

구분 동적 경로 (/user/<name>) 쿼리 스트링 (/search?q=val)
용도 리소스 고유 식별 (예: 유저, 글번호) 추가 조건, 검색, 필터링
코드 처리 함수 인자로 바로 전달받음 request.args.get()으로 받음
URL 형태 깔끔하고 정돈된 형태 ?와 &로 이어지는 형태

 

5. url_for: 하드코딩된 URL (예: href="/search?q=Flask") 대신, 함수 이름을 통해 URL을 생성해주는 함수

from flask import Flask, request
app = Flask(__name__)

@app.route('/search_link')
def search_link():  # url_for: q= 시작하면 search?q=Flask 로 변환
    return f'<a href="{url_for("search", q="Flask")}">Flask 검색하기</a>'
    # return f'<a href="/search?q={query}">Flask 검색하기</a>'
    
if __name__ == "__main__":
	app.run(debug=True)

 

6. redirect: 사용자를 다른 URL로 강제로 이동시킬 때 사용하는 아주 중요한 기능

  • redirect 동작 원리: 사용자가 어떤 페이지에 접속했을 때, 서버가 브라우저에게 HTTP 302 상태 코드와 함께 새로운 목적지 주소를 보냅니다. 그러면 브라우저는 서버가 시킨 대로 그 주소로 자동 이동합니다.
  • 코드 예시
from flask import Flask, redirect, url_for

app = Flask(__name__)

@app.route('/')
def home():
    return '여기는 홈 페이지입니다.'

# 사용자가 /old_page로 접속하면 /로 이동시킴
@app.route('/old_page')
def old_page():
    return redirect(url_for('home'))

if __name__ == '__main__':
    app.run(debug=True)

fl.ipynb
0.01MB

 

 

 

 

 

느낀점

 

지난주 마지막 과제가 힘들었어서 그 부분을 복습하기도 바쁜데 FLASK를 배웠다. 파이썬을 이제 프론트 쪽과 연결해서 사용할 수 있게 해주는 모듈인데, 또 새로운 개념을 들으니까 머리 속이 터지는 느낌이 들었다. 앞으로 이제 Flask는 사용해야할 때가 많을 것 같은데 초반부터 놓치면 안되기 때문에 수업을 놓치지 않기 위해 노력해야할 것 같다.  

 

 

 

 

 

 

 

 

 

 

——————————————————————————

본 후기는 [한글과컴퓨터x한국생산성본부x스나이퍼팩토리] 한컴 AI 아카데미 (B-log) 리뷰로 작성 되었습니다.